-
09-10-2019 - |
题
也许是一个天真的问题,但是...
确认或拒绝:
确定了编译时间的自动和静态存储持续时间的对象/变量的内存存在,并且程序绝对零可能会失败运行时,因为自动对象没有足够的内存。
当然,当自动对象的构造函数执行动态分配并且此类分配失败时,我们认为这是动态分配的失败,而不是自动分配。
解决方案
两个词: 堆栈溢出. 。 :p
其他提示
自动分配肯定会失败 - 通常称为堆栈溢出。当某人试图将大型数组作为局部变量时,您会经常看到这一点。无界(或不限制的)递归也可能引起这一点。
您无法在平台独立的方式中真正做的是检测自动分配失败并处理它。
在具有过度使用的系统(例如默认配置中的Linux)上,静态存储持续时间的对象甚至有可能在运行时导致故障。在程序启动时,这些对象将在零页面复制零页(如果是非初始化的)或盘中可执行文件的复制映射中存在。首次尝试写信给他们时,将发生页面故障,内核将为您的流程制作本地修改副本。如果内核是粗心的,并且没有像对该过程那样承诺的记忆力,那可能会失败,结果将是可怕的OOM杀手。
没有强大的系统有此问题,Linux行为可以通过:
echo "2" > /proc/sys/vm/overcommit_memory
不对。自动分配会导致堆栈溢出,这会导致我知道的大多数架构/平台上的即时过程终止。
同样,该程序可能无法从基础平台分配足够的空间为您的静态变量,在这种情况下,该程序仍将失败,但是在此之前会失败 main
叫做。
简单的反例:
#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;
}
例子:
#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;
}
不隶属于 StackOverflow