在以下代码段中,在free(x)
之后,为什么y
变为0?
根据我的理解,x
指向的堆中的内存仍然被y
指向,但是还没有分配给其他人,所以如何才能它改为0?
此外,我不认为free(x)
将其更改为0。
有任何意见吗?
#include <stdio.h>
int main(int argc, char *argv[])
{
int *y = NULL;
int *x = NULL;
x = malloc(4);
*x = 5;
y = x;
printf("[%d]\n", *y); //prints 5
free(x);
printf("[%d]\n", *y); //why doesn't print 5?, prints 0 instead
return 0;
}
答案 0 :(得分:12)
这是未定义的行为,解释只是推测。
我可以推测,你可能正在运行C库的调试版本,并且free()的调试版本确实将指向区域归零。
答案 1 :(得分:4)
free
所做的工作取决于实施。在释放内存后,不禁止将内存清零。
你正在做的是未定义的行为。
答案 2 :(得分:2)
不 y 指向与 x 相同的地址,行
y = x;
如果您释放 x ,您还可以释放 y 指向的内存。
如果你想知道为什么它打印'0',那个未定义的行为,但我之前已经看过它,一些程序员,将释放区域设置为'0'。
下载此视频名为"Binky the pointer fun video"(这不是一个玩笑,实际上非常有教育意义),你会得到更好的指示。
答案 3 :(得分:2)
对free()
的调用会将已由malloc()
分配的内存块放回到C运行时为堆维护的数据结构中(在这种情况下可能被称为'free的内容) -list)。
操作堆数据结构可能会偶然改变y
指向的内容(因为程序不再拥有内存,所以没有理由相信内存不应该更改)。
在程序的非调试版本中,运行时通常不会做任何特别的事情来使释放的内存无效,但正如我所提到的,它可能仍然会因为自己的簿记而进行更改(尽管因为内存不存在)不再属于调用者,允许运行时做任何它喜欢的事情。
在调试版本中,运行时可能会显式地将内存覆盖为一个值,如果程序确实使用该值,则希望它会导致更容易识别问题的问题。通常,用于覆盖释放的内存块的值不为零,因为零通常不会暴露错误(即NULL指针检查将导致代码“处理”无效的内存访问)。例如,MSVC的调试堆管理器将使用值0xDD覆盖释放的内存(有关详细信息,请参阅When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?)。