自动/静态内存分配

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

确认或否认:

自动和静态存储持续时间的对象/变量的内存的存在是在编译时确定的,并且由于没有足够的内存用于自动对象,程序将无法运行时运行。

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

两个字: Stack Overflow 。 :P

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

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

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

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

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

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

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

简单的反例:

 #include  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; } 

例:

 #include  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; }