C++标准对堆栈溢出有何规定
What does the C++ standard say about stack overflow?
我看了一下C++0x标准草案,据我所知,其中没有任何关于堆栈溢出的内容。搜索"堆栈溢出"没有结果,而搜索"堆栈"我只得到了堆栈展开和std::stack的引用。这是否意味着不可能有一个符合C++标准的实现,因为当内存被一个本地对象(如一个巨大的本地数组(耗尽时,不允许有任何机制来处理错误?
这个问题的答案表明,至少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失败吗?
编辑:问题不在于标准是否应该定义堆栈溢出时发生的情况,而在于它说了什么。
我不确定这是否是您想要的,但在C++03 ISO标准的附录B中有以下注意事项:
- 由于计算机是有限的,C++实现不可避免地会受到程序大小的限制可以成功处理。每次实施都应记录已知的限制。本文档可能会引用存在的固定极限,说明如何将可变极限计算为可用资源,或者说固定限制不存在或未知
- 这些限制可能会限制数量,包括以下描述的数量或其他数量
(我强调的是(我认为这意味着编译器允许其中一个函数工作,而另一个函数失败,这是完全合法的,前提是编译器说明了存在哪些限制,以及如何根据系统可用的资源计算这些限制。
行为未定义,因为标准没有定义超出资源限制的程序会发生什么。请注意,规范的附件B中有建议的限值。尽管该附件是非规范性的,实施过程可以忽略该附件,包括与其中规定的限值不同。在1.4[介绍合规性]中,规范中说
如果某个程序不违反本国际标准的规定,则合格实施应在其资源限制范围内接受并正确执行该程序。
没有任何内容说明一个不违反is规则但无法在实施的资源限制内接受和正确执行的程序会发生什么。因此,在这种情况下行为是不明确的。
堆栈溢出正在破坏操作系统现有的保护机制。这不是该语言的一个功能,因为所有机器可执行代码都有相同的保护。
如果您想捕捉这个特定的错误,您需要编写特定于操作系统的代码。例如,在Linux上,您需要捕获SIGSEGV(分段错误(信号。但是,请注意,这也可能是由于NULL指针的尊重或任何其他内存保护问题引起的,而不仅仅是堆栈溢出。
不确定是否使用Windows、OSX或移动设备。
堆栈溢出时发生的情况极其依赖于系统(CPU和操作系统,有时还依赖于编译器,因为它由编译器插入堆栈探测和其他安全扩展堆栈的机制(,因此不可能强制执行特定的响应;如果目标平台允许,最好的办法是建议更好的回应。大多数人不这样做;虽然有一种合理的方法来处理堆溢出,但当堆栈处于不一致状态时,可能会调用堆栈溢出处理程序(a(,其中有一个部分构建的堆栈帧,并且(b(可能涉及调用处理程序。。。这需要用于中断帧的堆栈空间。POSIX指定了一个sigaltstack()
机制,但它也有限制,并且ANSI C/C++不能合理地依赖于POSIX的遵从性。
- 'short int'持有的值溢出,但"自动"不会溢出?
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 大于65535的C++数组[size]引发不一致的溢出
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- C++中无符号字符溢出
- Python中的for循环与C++有何不同
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 整数溢出,最大值为 pow(10,19)
- 获取隐式转换溢出从无符号到已签名的警告
- 使用 strcat 获取缓冲区溢出错误
- LeetCode 1:两和 - 地址清理器:堆缓冲区溢出地址
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 在C++中释放内存期间,迭代器与指针有何不同
- C++ 对象数组堆栈溢出
- C++17标准对在nullptr上调用delete有何规定
- 关于在矢量上调用clear如何改变容量,标准有何规定
- C++标准对堆栈溢出有何规定
- c++中栈溢出和分段错误的危险