以下是代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p;
p=(int *)malloc(sizeof(int));
*p=5;
printf("Before freeing=%p\n",p);
printf("Value of p=%d\n",*p);
//making it dangling pointer
free(p);
printf("After freeing =%p\n",p);
printf("Value of p=%d\n",*p);
return 0;
}
以下是输出:
Before freeing=0x1485010
Value of p=5
After freeing =0x1485010
Value of p=0
释放指针后,取消引用会输出“0”(零)。
下面是另一个也给出'0'
的代码include <stdio.h>
#include <stdlib.h>
int main()
{
int *p;
p=(int *)malloc(sizeof(int));
printf("Before freeing=%p\n",(void *)p);
printf("Value of p=%d\n",*p);
return 0;
}
在这个我没有释放内存,只是分配它,仍然给它'0'。 是否像每个未初始化指针的默认值是'0'??
为什么会这样?
答案 0 :(得分:4)
不要依赖于此,这是未定义的行为。 free()
不必将指针设置为零,这正是您当前的实现正在为您做的事情。如果您想100%确定,无论您的编译器,平台等如何,请在释放后将指针设置为NULL
。
答案 1 :(得分:3)
如果我们查看涵盖未定义行为
的C99草案标准Annex J.2
,那么这只是undefined behavior:
在以下情况下,行为未定义:
并包括以下项目符号:
指向通过调用free或者释放释放的空间的指针的值 使用realloc函数(7.20.3)。
在释放后将指针设置为NULL
通常是一个好主意,您可以在该主题上找到good discussion here。
答案 2 :(得分:1)
取消引用无效指针会导致每个规范的未定义结果。 不能保证失败。
答案 3 :(得分:1)
虽然答案“无关紧要,但它是UB”通常是足够的,但人们可能会好奇为什么值会发生变化。好奇心是(恕我直言)了解事情发生原因的正当理由。
这取决于可能决定存储“下一个空闲块”的地址的内存管理或任何在释放的内存区域中的内容。
所以你观察到的可能是内存管理的一个动作。
例如,内存管理可以通过管理两个链表和一个上指针的方式实现。一个链表包含分配的内存块,指向“真正可用”内存之前的8或16个字节,另一个链表指向第一个空闲块,而第一个空闲块又包含指向下一个空闲块的指针。上部指针上方的内存被视为空闲。
如果释放第一个内存块,则空闲列表指针指向它,并且其第一个指针大小的数据被清零,这意味着没有其他释放的块。你有理由把记忆清零。
很高兴知道这些事情存在以及它们如何运作,但是避免在生产计划中利用这些知识的诱惑。有一天,他们可能会站起来......