为什么在“free”之后取消引用C指针给出值0

时间:2013-10-22 16:17:36

标签: c pointers

以下是代码:

#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'??

为什么会这样?

4 个答案:

答案 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个字节,另一个链表指向第一个空闲块,而第一个空闲块又包含指向下一个空闲块的指针。上部指针上方的内存被视为空闲。

如果释放第一个内存块,则空闲列表指针指向它,并且其第一个指针大小的数据被清零,这意味着没有其他释放的块。你有理由把记忆清零。

很高兴知道这些事情存在以及它们如何运作,但是避免在生产计划中利用这些知识的诱惑。有一天,他们可能会站起来......