3

在下面的代码段中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;
}
4

4 回答 4

12

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

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

于 2010-04-01T07:22:21.443 回答
4

做什么free取决于实现。不禁止内存释放后清零。

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

于 2010-04-01T07:21:51.927 回答
2

行后y是否指向与x相同的地址

y = x;

如果你释放x,你也将释放y指向的内存。

如果您想知道为什么它会打印“0”,即未定义的行为,但我之前将其视为一种做法,一些程序员将释放区域设置为“0”。

下载这个名为“Binky 指针趣味视频”的视频(这不是开玩笑,实际上很有教育意义),你会得到更好的指针。

于 2010-04-01T07:27:08.753 回答
2

调用free()将把已分配的内存块malloc()放回 C 运行时为堆维护的数据结构上(在这种情况下,可能称为“空闲列表”)。

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

在程序的非调试版本中,运行时通常不会专门做任何事情来使释放的内存无效,但正如我所提到的,它仍然可能由于它自己的簿记而进行更改(尽管因为内存不属于对调用者来说,运行时可以做任何它喜欢的事情)。

在调试版本中,运行时可能会显式地将内存覆盖为一个可能无效的值,如果程序确实使用它,希望它会导致更容易识别问题的问题。通常用于覆盖已释放内存块的值不为零,因为零通常不会暴露错误(即 NULL 指针检查将导致代码“处理”无效的内存访问)。例如,MSVC 的调试堆管理器将使用值 0xDD 覆盖已释放的内存(有关更多详细信息,请参阅操作系统何时以及为什么在 malloc/free/new/delete 上将内存初始化为 0xCD、0xDD 等?)。

于 2010-04-01T07:31:35.830 回答