未初始化的堆和堆栈空间值

时间:2009-07-07 17:12:55

标签: stack heap

为什么堆空间始终设置为零? 为什么堆栈空间同样没有设置为零??

4 个答案:

答案 0 :(得分:4)

堆空间并不总是设置为零。

答案 1 :(得分:4)

答案取决于您使用的语言(C ++,Java等),可能在哪个编译器上,也可能在编译器选项上(调试与发布)。此外,行为可能无法保证(当您第一次分配它时,分配的堆可能为零,但是在您的程序运行之后并且您开始重用堆时,您可能会发现您正在重新分配非归零内存)。

答案 2 :(得分:2)

如果堆空间设置为零,可能是因为它之前没有使用过。 在堆上分配,释放和重新分配大量内容之后,您将开始在未初始化的堆空间中找到一些旧数据。

堆栈包含调用堆栈中其他函数的旧本地变量。堆栈的设计尽可能高效,因此没有时间擦除旧变量。

还要记住,0不一定是任何东西的正确初始化者......这只是一个明智的选择;没有什么能让它独一无二“正确”。您应该始终为局部变量显式设置初始化值!

答案 3 :(得分:2)

您所看到的是您的环境的文物,而不是赠品。我假设你在谈论C。

但是说,当你从堆中分配内存时,它可能会也可能不会被初始化为零。在像C这样的语言中,malloc不保证将内存初始化为0,但calloc确实如此。然而,这说,实际上,如果你分配了很多东西,你往往会看到它充满了0。为什么?因为当你的程序耗尽空间给你内存时,它会要求操作系统提供更多内存。当它这样做时,操作系统通过映射它实际上实现的一堆虚拟页面并在第一次访问时填充0来为其提供内存。现在,如果您在堆上释放一些值并使用malloc分配更多值,您可能会收到一些您之前描述的“脏”内存。如果您假设所有内容都将初始化为0,则可能会导致细微的错误,只有在系统运行一段时间后,或者在系统完全不同的部分进行删除后才会发生!

所以不要依赖初始化为0的堆上的fresg空间,除非你要求它显式初始化内存。

至于为什么堆栈更糟糕,堆重用空间导致随机噪声在你刚刚分配的内存中的相同问题发生在堆栈上,但问题更糟,因为从函数调用返回后,你的程序只是在你上面的堆栈中乱写了一堆东西,并没有费心去清理它。所以你几乎总是在上面的“脏”案例中。

最后,最好确保在读取之前将您计划使用的所有内容初始化为已知状态。