当进程请求内存和操作系统向进程提供一些新的页面时,内核应该初始化页面(例如零),以避免显示另一个进程使用的可能有信心的数据。在进程启动和接收某些内存(例如堆栈段)时也是如此。
当我在Linux中执行以下代码时,结果是大部分分配的内存确实是0,但是堆栈底部的大约3-4 kB (数组的最后一个元素,最高地址)包含随机数。
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
int * a = (int*)alloca(sizeof(int)*2000000);
for(int i = 0; i< 2000000; ++i)
cout << a[i] << endl;
return 0;
}发布于 2011-03-10 22:18:06
我非常肯定,当操作系统启动您的进程时,堆栈只是零。我认为你所观察到的是另一种现象。您似乎已经将程序编译为C++。C++在启动main之前做了很多代码(构造函数等等)。因此,您看到的是您自己执行的剩余值。
如果您将代码编译为C(更改为"stdio.h“等),您可能会看到”污染“大大减少,甚至一点也没有。特别是,如果您要静态地将您的程序链接到C库的极简版本。
发布于 2011-03-10 21:44:48
操作系统并不保证内存为零,只保证你拥有它。它可能会为您提供以前使用过的内存页(或者以前从未使用过,但不是零)。如果应用程序存储可能敏感的数据,那么在空闲()‘ing之前,它将对数据进行零化。
它没有设置为零,因为这将是执行不必要的工作。如果你分配20兆字节来存储一个纹理或几帧视频,为什么操作系统会把零写到所有的内存中,这样你就可以把它们重写为你接下来要做的事情了。
一般情况下,操作系统不会做任何他们不需要做的事情。
编辑:为了稍微扩展一下,当您“分配”一个内存块时,操作系统所做的就是从一个未分配的页面池中重新分配内存页(通常为4096字节)。您还可以拥有共享内存,在这种情况下,操作系统会将它们“分配”给多个进程。这就是所有的分配金额。
发布于 2011-03-10 21:56:23
当您通过brk()、sbrk()或mmap()将新内存输入到进程中时,就可以保证将其归零。
但是,流程堆栈已经分配给您的进程。alloca()函数没有获得新的堆栈空间,它只返回当前堆栈指针并将指针移动到新块的末尾。
因此,alloca()返回的内存块以前已经被您的进程使用过。即使在main中的alloca()之前没有函数,C库和动态加载器也一直在使用堆栈。
https://stackoverflow.com/questions/5266260
复制相似问题