2010-04-01 20 views
2

在以下代码段中,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; 
} 
+2

我的评论:不这样做 – 2010-04-01 07:26:30

+2

**鼻魔** – jschmier 2010-04-01 07:35:09

+3

太阳耀斑。这几乎总是因为太阳耀斑。 – 2010-04-01 07:54:32

回答

4

free中所做的工作取决于实施。释放内存后不会禁止内存清零。

而你在做什么是未定义的行为。

12

这是未定义的行为,解释只是猜测。

我可以推测,也许你正在运行C库的调试版本,并且free()的调试版本将零点指向区域。

+0

绝对是。这个问题实际上没有意义,因为没有明确的答案。 – Cruachan 2010-04-01 07:32:18

+0

除了通常调试堆管理器将显式地使用* zero以外的内容填充释放的内存。 – 2010-04-01 07:39:57

+2

@Cruachan - 不完全没有意义,答案相当明确,未定义。未定义未定义。 – 2010-04-01 07:54:08

2

ý指向相同的地址X,行之后

Y = X;您可以免费使用指向的内存。

如果你想知道为什么它会打印'0',那么这个未定义的行为,但我认为它是一种习惯,有些程序员将释放区域设置为'0'。

下载这个视频叫做"Binky the pointer fun video"(这不是玩笑,实际上很有教育意义),你会更好地指出。

+1

我明白了什么是悬摆指针!我只是想了解Y = 0的行为。在视频-http使用 – 2010-04-01 07:33:26

+0

相同的代码例如://cslibrary.stanford.edu/106/ – jschmier 2010-04-01 07:34:54

2

free()调用会将这个已被malloc()分配返回到该C运行时保持用于堆(在这种情况下,一些可能被称为“自由列表)数据结构的内存块。

操纵堆数据结构可能会偶然改变y指向的内容(因为程序不再拥有内存,所以没有理由相信内存不应该改变)。

在程序的非调试版本中,运行时通常不会执行任何特别的操作来使释放的内存无效,但正如我所提到的,它可能仍会因其自己的簿记而发生更改(尽管自内存不再属于调用者,运行时可以做任何喜欢的事情)。

在调试版本中,运行时可能会明确地将内存覆盖到一个值,如果程序确实使用它,希望它会导致更容易识别问题的问题。通常用于覆盖释放的内存块的值不为零,因为零通常不会暴露错误(即NULL指针检查会导致代码“处理”无效的内存访问)。例如,MSVC的调试堆管理器将用值0xDD覆盖释放的内存(有关更多详细信息,请参阅When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?)。