首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何初始化堆栈?

如何初始化堆栈?
EN

Stack Overflow用户
提问于 2011-03-10 21:41:37
回答 5查看 4.5K关注 0票数 16

当进程请求内存和操作系统向进程提供一些新的页面时,内核应该初始化页面(例如零),以避免显示另一个进程使用的可能有信心的数据。在进程启动和接收某些内存(例如堆栈段)时也是如此。

当我在Linux中执行以下代码时,结果是大部分分配的内存确实是0,但是堆栈底部的大约3-4 kB (数组的最后一个元素,最高地址)包含随机数。

代码语言:javascript
复制
#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;
}

  1. 为什么没有设置为零?
  2. 可能是因为它被进程重用了吗?如果是的话,
  3. 会不会是之前使用了3-4 kB的初始化代码?
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-10 22:18:06

我非常肯定,当操作系统启动您的进程时,堆栈只是零。我认为你所观察到的是另一种现象。您似乎已经将程序编译为C++。C++在启动main之前做了很多代码(构造函数等等)。因此,您看到的是您自己执行的剩余值。

如果您将代码编译为C(更改为"stdio.h“等),您可能会看到”污染“大大减少,甚至一点也没有。特别是,如果您要静态地将您的程序链接到C库的极简版本。

票数 4
EN

Stack Overflow用户

发布于 2011-03-10 21:44:48

操作系统并不保证内存为零,只保证你拥有它。它可能会为您提供以前使用过的内存页(或者以前从未使用过,但不是零)。如果应用程序存储可能敏感的数据,那么在空闲()‘ing之前,它将对数据进行零化。

它没有设置为零,因为这将是执行不必要的工作。如果你分配20兆字节来存储一个纹理或几帧视频,为什么操作系统会把零写到所有的内存中,这样你就可以把它们重写为你接下来要做的事情了。

一般情况下,操作系统不会做任何他们不需要做的事情。

编辑:为了稍微扩展一下,当您“分配”一个内存块时,操作系统所做的就是从一个未分配的页面池中重新分配内存页(通常为4096字节)。您还可以拥有共享内存,在这种情况下,操作系统会将它们“分配”给多个进程。这就是所有的分配金额。

票数 12
EN

Stack Overflow用户

发布于 2011-03-10 21:56:23

当您通过brk()sbrk()mmap()将新内存输入到进程中时,就可以保证将其归零。

但是,流程堆栈已经分配给您的进程。alloca()函数没有获得新的堆栈空间,它只返回当前堆栈指针并将指针移动到新块的末尾。

因此,alloca()返回的内存块以前已经被您的进程使用过。即使在main中的alloca()之前没有函数,C库和动态加载器也一直在使用堆栈。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5266260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档