为什么堆空间总是设置为零?为什么堆栈空间同样不设置为零?
4 回答
堆空间并不总是设置为零。
答案取决于您使用的语言(C++、Java 等),可能取决于哪个编译器,也可能取决于编译器选项(调试与发布)。此外,可能无法保证行为(首次分配时分配的堆可能为零,但稍后在您的程序运行并开始重用堆后,您可能会发现您正在 [重新] 分配非零内存)。
如果堆空间设置为零,可能是因为之前没有使用过。在堆上分配、释放和重新分配大量内容后,您将开始在未初始化的堆空间中发现一些旧数据。
堆栈包含来自调用堆栈中其他函数的旧局部变量。堆栈旨在尽可能高效,因此无需花费时间擦除旧变量。
还要记住,0 不一定是任何东西的正确初始化器......这只是一个明智的选择;没有什么可以让它独一无二地“正确”。您应该始终为局部变量显式设置初始化器值!
你所看到的是你的环境的产物,而不是给定的。我假设你在谈论C。
但是就是说,当您从堆中分配内存时,它可能会或可能不会初始化为零。在像 C 这样的语言中,malloc 不保证内存被初始化为 0,但 calloc 可以。然而,这就是说,在实践中,如果你分配了很多东西,你往往会看到它充满了 0。为什么?因为当你的程序没有足够的空间给你内存时,它会要求操作系统提供更多内存。当它这样做时,操作系统通过映射一堆虚拟页面来给它内存,它会在第一次访问时实际实现并用 0 填充。现在,如果您在堆上释放一些值并使用 malloc 分配更多值,您可能会得到一些您之前写下的“脏”内存。如果您假设所有内容都将初始化为 0,
所以不要依赖堆中的fresg空间被初始化为0,除非你要求它显式地初始化内存。
至于为什么堆栈更糟糕,在堆栈上重用空间导致随机噪声出现在您刚刚分配的内存中的相同问题发生在堆栈上,但问题更糟糕,因为在您从函数调用返回后,您的程序只是在你上方的堆栈上乱涂乱画了一堆东西,并没有费心去清理它。因此,您几乎总是处于上述“肮脏”的情况。
最后,最好确保确保您计划使用的所有内容在读取之前都已初始化为已知状态。