动态内存开辟

来源:互联网 发布:股票分析算法 编辑:程序博客网 时间:2024/05/17 02:09

动态内存开辟的函数有malloc、realloc、calloc、free函数,接下来对每一个函数进行解释及使用,并总结出几个经典的例子巩固,以及总结常见的错误。

1.malloc & free基本使用

int main(){int* p = malloc(10 * sizeof(int));if (p == NULL){perror("error");}//...free(p);p = NULL;return 0;}
2.realloc & free基本使用

int main(){int *p = malloc(12);int *ptr = NULL;if (p = NULL){perror("error");//printf("%s\n",strerror);}//...ptr = realloc(p, 120);if (ptr != NULL){p = ptr;}free(p);p = NULL;return 0;}
realloc一般用于malloc后边空间不可用,重新开辟一个空间。

3.calloc & free基本使用

int main(){int *p = calloc(4, sizeof(int));//...free(p);p = NULL;return 0;}
calloc函数有两个参数,分别为个数、字节大小,并且初始化全为0
注意:realloc(NULL,10) ;    等价于   malloc(10) ;

现在就几个经典的例子来讲一下动态内存开辟中经常出现的错误
典例1:

void GetMemory(char *p, int num){p = (char *)malloc(sizeof(char) * num);}void Test(void){char *str = NULL;GetMemory(str, 100);strcpy(str, "hello");}int main(){Test();system("pause:");return 0;}
程序崩溃,内存泄露。
分析:
1.在Test函数内部,str以值传递的形式给GetMemory函数,GetMemory函数形参p是str的一份临时拷贝,在GetMemory函数内部用p接收动态开辟好内存地址,str并没有发生变化,等GetMemory函数返回之后,str依然保持空指针,strcpy将“hello”拷贝到NULL,访问内存出错。
2.p所指向的空间找不到了,所以存在内存泄露问题。

更改:

void GetMemory(char **p, int num){*p = (char *)malloc(sizeof(char) * num);}void Test(void){char *str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf("%s\n", str);}int main(){Test();system("pause:");return 0;}
典例2:
用函数返回值来传递动态内存

char* GetMemory(int num){char*p = (char*)malloc(sizeof(char)*num);}void Test(void){char *str = NULL;str = GetMemory(100);strcpy(str, "hello");printf("%s\n", str);free(str);}int main(){Test();system("pause:");return 0;}
典例3:

char *GetString(void){char p[] = "hello world";return p;}void Test(void){char *str = NULL;str = GetString();printf("%s\n", str);}int main(){Test();system("pause:");return 0;}
产生一个随机值。
分析:
在Test函数内部,指针变量str是空指针,调用GetString函数,在GetString函数内部创建一个数组,里边的内容是“hello world”,p是一个局部变量,返回存放的地址,函数调用结束,内存释放,“hello world”销毁。str可以指向,但不能访问。就不能输出,“hello world”。
典例4:

int main(){char *p = (char*)malloc(100);strcpy(p, "hello");free(p);//...if (p != NULL){strcpy(p, "world");}return 0;}


分析:
p被free后其地址仍然不变,p所指的内容被释放,p就成了野指针。应该将p置为NULL。
而这里没有起到防护作用,拷贝的时候就出错。



总结(常见错误):
1.对空指针进行解引用
2.内存访问越界
3.释放非动态开辟内存
4.释放动态内存一部分
5.释放同一块动态内存多余1次
6.忘记释放


原创粉丝点击