繁体   English   中英

C++ 标准对堆栈溢出有何规定?

[英]What does the C++ standard say about stack overflow?

我查看了 C++0x 标准草案,据我所知,那里没有任何关于堆栈溢出的内容。 搜索“堆栈溢出”没有结果,搜索“堆栈”我只得到了对堆栈展开和 std::stack 的引用。 这是否意味着不能有符合 C++ 标准的实现,因为当 memory 被本地 object 耗尽时,没有允许处理错误的机制?

这个问题的答案表明,至少 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 的 memory(想象一下 function 实际上使用了巨大的数组,因此编译器无法静默地将其删除而不会产生不良影响)。 C++ 标准是否允许程序 A 失败?

编辑:问题不在于标准是否应该定义堆栈溢出时会发生什么,问题是它说了什么,如果有的话。

我不确定这是否是您要查找的内容,但在 C++03 ISO 标准的附录 B 中有以下通知:

  1. 由于计算机是有限的,C++ 实现不可避免地受限于它们可以成功处理的程序的大小。 每个实施都应在已知的情况下记录这些限制。 本文档可能会引用存在的固定限制,例如如何将可变限制计算为可用资源的 function ,或者说固定限制不存在或未知。
  2. 这些限制可能会限制包括以下描述的数量或其他数量。

(我的重点)我认为这意味着编译器允许其中一个函数在另一个函数失败时工作是完全合法的,只要编译器说明存在哪些限制以及如何从系统可用的资源中计算它们.

行为未定义,因为标准没有定义超出资源限制的程序会发生什么。 请注意,规范的附录 B 中有推荐的限制。 尽管该附件是非规范性的,但实施可以忽略该附件,包括具有与此处指定不同的限制。 在 1.4 [intro.compliance] 中,规范说

如果程序不违反本国际标准中的规则,则符合要求的实现应在其资源限制内接受并正确执行该程序。

没有什么可以说明不违反 IS 规则但不能在实现的资源限制内被接受和正确执行的程序会发生什么。 因此,对于这种情况,行为是未定义的。

堆栈溢出正在破坏操作系统已有的保护机制。 它不是该语言的特性,因为所有机器可执行代码都将具有相同的保护。

如果你想捕捉这个特定的错误,你需要编写操作系统特定的代码。 例如,在 Linux 上,您需要捕获 SIGSEGV(分段错误)信号。 但是,请注意,这也可能由 NULL 指针引用或任何其他 memory 保护问题引起,而不仅仅是堆栈溢出。

不确定 Windows、OSX 或移动设备。

堆栈溢出时发生的情况非常依赖于系统(CPU 和操作系统,有时还有编译器,因为由编译器插入堆栈探测器和其他安全扩展堆栈的机制),因此不可能强制执行特定响应; 如果目标平台允许,最好的办法是提出更可取的回应。 大多数没有; 虽然有一种合理的方法来处理堆溢出,但堆栈溢出处理程序 (a) 可能会在堆栈位于不一致的 state 中时被调用,并且上面有部分构造的堆栈帧,并且 (b) 可能涉及调用一个处理程序......它需要用于中断帧的堆栈空间。 POSIX 指定了sigaltstack()机制,但它也有限制,并且 ANSI C C/C++ 不能合理地依赖于 POSIX 合规性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM