为准确了解free函数,让我们看看malloc申请动态内存和free函数被调用时,内存做了哪些工作:
int main()
{
int *arr=(int*)malloc(10*sizeof(int));
arr[0] = 100;
arr[1] = 200;
free(arr);
arr = NULL;
char src[]={"shit man"};
char *str = (char*)malloc(10);
strcpy(str,src);
free(str);
str = NULL;
return 0;
}
申请40个字节的内存块大小为28,在被申请内存块首地址的16字节之前被写入;
调用free函数后,之前申请的内存块被覆盖;
接着申请10个字节大小的内存块,转成16进制为0a,在内存块首地址的16字节之前被写入到内存里;
使用free函数释放内存时,函数在内存块首地址之前16个字节处找到内存块的大小。
因此若被free的为一个空指针是没有任何意义的,编译器也不会报错。
申请字符串函数,初始化遇到问题
char* ArrChar()
{
char *arr = (char*)malloc(10*sizeof(char));
return arr;
}
int main()
{
char *p=ArrChar();
free(p);
return 0;
}
由于未初始化的指针自动初始化为0xcccccccc或0xcdcdcdcd,而不是取随机值,使用strcpy函数,可以进行正确的初始化。
如果内存不够的情况,函数库为我们提供了另一个函数realloc,
int main()
{
int *p = (int*)malloc(10*sizeof(int));
for(int i=0; i<10; i++)
{
p[i]=i;
}
int tmp = 0;
p = (int*)realloc(p,100*sizeof(int));
for(int i=0; i<20; i++)
{
p[i]=i;
}
tmp = 1;
p = (int*)realloc(p,5*sizeof(int));
for(int i=0; i<5; i++)
{
p[i]=i;
}
return 0;
}
监视p 的地址为
动态申请长度为40字节的内存
使用realloc函数,得到长度为400字节的内存,p的地址仍为
调用realloc函数,得到新的长度为20字节的内存,p的地址为
本次测试realloc函数申请更大或更小内存,指针的位置均为发生改变,原来的内存已经被覆盖。
参考文献:
free函数是如何确定要释放多少内存空间的