【发布时间】:2011-07-05 23:20:20
【问题描述】:
我查看了 C++0x 标准草案,据我所知,其中没有任何关于堆栈溢出的内容。搜索“堆栈溢出”没有结果,搜索“堆栈”我只得到了对堆栈展开和 std::stack 的引用。这是否意味着不存在符合 C++ 标准的实现,因为当本地对象(例如巨大的本地数组)耗尽内存时,没有允许处理错误的机制?
this question 的答案表明至少 C 标准没有提到堆栈溢出。
为了使问题具体化,请考虑这个程序
// Program A
int identity(int a) {
if (a == 0)
return 0;
char hugeArray[1024 * 1024 * 1024]; // 1 GB
return identity(a - 1) + 1;
}
int main() {
return f(1024 * 1024 * 1024);
}
还有这个程序
// program B
int main() {
return 1024 * 1024 * 1024;
}
我认为 C++ 标准不允许任何 C++ 实现在这两个程序上做明显不同的事情。实际上,程序 A 不会在任何现代机器上运行,因为它在堆栈上分配了 EB 的内存(想象一下该函数实际上使用了巨大的数组,因此编译器无法静默删除它而不会产生不良影响)。 C++ 标准是否允许程序 A 失败?
编辑:问题不是标准是否应该定义堆栈溢出时会发生什么,问题是什么,如果有的话。
【问题讨论】:
-
该标准没有内存有限的物理计算机的概念。原则上,任何编译器都不可能符合标准,因为您总是可以编写一个 非常 大的程序,该程序不适合任何现有硬件并且无法编译,尽管它由有效的标准代码组成,但编译器无法编译。
-
@Kerrek 好点。但是,就新的抛出 std::bad_alloc 而言,该标准确实具有内存是有限资源的概念。如果我使用 new 分配了巨大的数组,标准 将 允许程序 A 失败。我想知道是否有类似的概念允许程序 A 失败。
-
你当然可以期待
new char[HUGE]失败,当然。但是,如果您的源代码包含数十亿个函数怎么办?所有完全有效的标准 C++... -
堆在某种程度上是显式分配的;堆栈是自动分配的,唯一可用的控制通常是堆栈探测器以强制扩展堆栈。这意味着您无法事先检查并且通常无法处理甚至识别堆栈运行到堆中的情况。 (想一想:这是一个超大的堆栈分配还是一个野堆指针?程序员可以通过检查代码(希望如此)来解决这个问题,但内核和系统库都不能。)
-
堆栈是一个实现细节,无论是 C 还是 C++ 标准都不会触及十英尺的柱子。这并不少见,VM 语言也会混淆它。这普遍符合“哦,废话,我们不要再这样做了”的类别。如果你的堆栈用完了,那么你的数量级就超出了合理范围。
标签: c++ stack-overflow undefined-behavior