在编写很多程序时,我们无法提前预知需要多少内存来存储某个定义变量(数组)中的特定信息,所需内存的大小需要在真正运行时才能确定。动态内存的优点在于函数执行完毕之后仍然可以被其他函数使用。
动态内存的释放:使用free;free掉一个指针,只是将指针指向的内存空间释放掉了,并没有将指针置为NULL,指针仍指向被释放掉的内存的地址,在判断指针是否为NULL的时候,通常是通过if(pt == NULL) ,这时,导致指针成为了野指针。并且野指针和空指针不同,野指针有地址,或者说是指向内存,对野指针进行操作,会造成内存错误,并且野指针无法从if语句进行判断其是否为NULL,所以在指针释放之后要将指针置为NULL。free 释放的是指针指向的内存。而指针是一个变量,只有程序结束时才被销毁。申请了内存不能不free,也不能多次free。而多次free会导致系统崩溃(非法写内存)。
举个简单例子:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[5];
int len;
int *pArr;
int i = 0;
//malloc只有一个形参,并且是整型
// 4表示请求系统为本程序分配四个字节
printf("input\n");
scanf("%d", &len);
pArr = (int *)malloc(sizeof(int) * len);
for (i=0; i<len; i++)
{
scanf("%d", &pArr[i]);
}
for (i=0; i<len; i++)
{
printf("%d\n", pArr[i]);
}
realloc(pArr, sizeof(int) * (len+2));
for (i=0; i<len+2; i++)
{
printf("%d\n", pArr[i]);
}
free(pArr);
return 0;
}
多次free会导致系统崩溃, 下面介绍避免多次free的方法(利用宏定义):
#include <stdio.h>
#include <stdlib.h>
#define FREE(p) myfree((void **)&p) // 防止内存泄漏
void myfree(void ** point)
{
if(*point != NULL)
{
free(*point);
*point = NULL;
}
}
int main()
{
char * name = NULL;
FREE(name);
FREE(name);
FREE(name);
printf("no problem11111111\n");
name = (char *) malloc(10);
if(name)
{
printf("allocate successful\n");
printf("地址为: %p\n",name);
}
else
{
printf("allocate failed\n");
}
FREE(name);
FREE(name);
printf("no problem2222222\n");
return 0;
}