自动/静态内存分配

时间:2010-12-07 17:02:47

标签: c++ c memory-management operating-system virtual-memory

也许是一个天真的问题,但是......

确认或拒绝:

自动和静态存储持续时间的对象/变量的内存的存在是在编译时确定的,并且由于没有足够的内存用于自动对象,程序运行失败的可能性绝对为零。 / em>

当然,当自动对象的构造函数执行动态分配并且这样的分配失败时,我们认为这是动态分配的失败,而不是自动的。

6 个答案:

答案 0 :(得分:14)

自动分配肯定会失败 - 这通常称为堆栈溢出。当有人试图将变量大的数组作为局部变量时,你经常会看到这种情况。无限制(或无限制)递归也可能导致这种情况。

您无法以独立于平台的方式真正做到的是检测自动分配失败并处理它。

答案 1 :(得分:13)

两个字:Stack Overflow。 :P

答案 2 :(得分:4)

在具有过度使用的系统上(例如,默认配置中的Linux),静态存储持续时间的对象甚至可能在运行时导致失败。在程序启动时,这些对象将存在于写入时写入零页(如果它们未初始化)或磁盘上可执行文件的写时复制映射中。在第一次尝试写入它们时,将发生页面错误,内核将为您的进程制作本地可修改的副本。如果内核粗心并且没有保留与提交给进程一样多的内存,那么这可能会失败,结果将是可怕的OOM杀手。

没有强大的系统存在此问题,Linux行为可以通过以下方式修复:

echo "2" > /proc/sys/vm/overcommit_memory

答案 3 :(得分:2)

不正确。自动分配可能导致堆栈溢出,从而导致我知道的大多数架构/平台上的即时进程终止。

此外,程序可能无法为底层平台的静态变量分配足够的空间,在这种情况下程序仍会失败,但在调用main之前它将失败。

答案 4 :(得分:0)

简单的反例:

#include <string.h>

int main()
{
    int huge[0x1FFFFFFF]; // Specific size doesn't matter;
                          // it just has to be bigger than the stack.

    memset(huge, 0, sizeof(huge) / sizeof(int));

    return 0;
}

答案 5 :(得分:-1)

示例:

#include <iostream>

using namespace std;

class A
{
public:
    A() { p = new int[0xFFFFFFFF]; }

private:
    int* p;
};

static A g_a;

int main()
{
    cout << "Why do I never get called?" << endl;
}