4

也许是一个幼稚的问题,但是...

确认或否认:

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

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

4

6 回答 6

14

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

你不能以独立于平台的方式真正做的是检测自动分配失败并处理它。

于 2010-12-07T17:05:26.053 回答
13

两个字:堆栈溢出。:P

于 2010-12-07T17:06:58.567 回答
4

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

没有健壮的系统有这个问题,Linux 行为可以通过以下方式修复:

echo "2" > /proc/sys/vm/overcommit_memory
于 2010-12-07T17:25:20.743 回答
2

不对。自动分配会导致堆栈溢出,这会导致我知道的大多数架构/平台上的即时进程终止。

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

于 2010-12-07T17:06:07.273 回答
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;
}
于 2010-12-07T17:09:23.973 回答
-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;
}
于 2010-12-07T17:13:05.830 回答