malloc和free是常用的动态内存申请和释放函数,功能就不赘述了,尤其在调用 free 后,我们脑海中想到的就是释放之前申请的内存区域,那么我们再细究一下,调用free(p) 后,指针p值和 p指向的内存状态是什么样呢?说下答案吧:
1、调用free(p) 后,p值不变。
2、调用free(p) 后,p指向的内存的值不确定,有可能变,也有可能不变。
这里就说明了一个容易忽略的结果:
调用free(p) 之后,只是将p所指向的之前申请的内存区域标志为已回收,可以由malloc函数,再次申请,但是p值和p指向的内存内容并不会自动清空。
我们用一段程序来验证一下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int *p;
int i;
/* 申请一段内存区域,用指针p指向 */
p = (int *)malloc(10*sizeof(int));
if(p == NULL){
printf("malloc fail.\n");
}
/* 给申请的内存赋值 */
for(i = 0; i < 10; i++){
p[i] = i;
}
/* 打印指针信息、内存信息 */
printf("before free p's addr:%ld, data:", p);
for(i = 0; i < 10; i++) {
printf("<%d>", p[i]);
}
printf("\n");
/* 释放并打印内存信息 */
free(p);
printf("after free p's addr:%ld, data:", p);
for(i = 0; i < 10; i++) {
printf("<%d>", p[i]);
}
printf("\n");
return 0;
}
程序运行结果如下:
可见,我们需要注意这一点,当free(p),我们就不要再对p做任何操作了,因为这个并不会立即报错,而且运气好的话,p指向的内存区域没有被重新申请,那么里面的值也是不变的,但是一旦像图中,有部分内存值改变,另一部分不变的时候,那么对于程序逻辑来说就很麻烦了。所以我们在使用free后,最好再 给p赋值为NULL,当然不能在函数内,因为函数会传值,比如
void delete(void *p)
{
free(p);
p = NULL; //这样是没用的,因为函数是传值调用
}
void delete(void *p)
{
free(p);
}
p = NULL; // 函数体外赋值是可以的。