如何创建无限递归,这将抛出堆栈溢出异常
How to create endless recursion which will throw stack overflow exception?
我试图用以下程序创建堆栈溢出运行时异常:
void f(int a) {
cout << a << ", ";
f(++a);
}
int main () {
f(0);
return 0;
}
当我运行这个程序时,我的计算机运行大约261824 call stack
,然后command terminated
运行时错误发生了。现在我想知道:
- 这是一个堆栈溢出的好例子吗?如果是,为什么会出现
- 如何处理
try
,catch
堆栈溢出异常? - 我有很多空闲内存;为什么我的堆栈没有使用我所有的内存?
- 如何确定堆栈的大小对应于我的
call stack
?
command terminated
错误?这些都是实现细节。从技术上讲,c++实现不需要堆栈,它只需要自动存储。至少有一种C实现在堆中使用链表(好吧,从我的理解来看,这是一个奇怪的系统)来实现它们的自动存储。
但是,通常情况下,堆栈是一个连续的内存地址空间区域,进程只保留它来存储自动变量和调用帧。它必须在发生任何其他事情之前被保留,因为它必须是连续的,如果一些内存块被分配用于其他目的,堆栈将无法增长。
如果您想将整个内存地址空间用于堆栈,则没有空间用于堆(即自由存储)。所以堆栈不会使用所有的内存…
1mb是将堆栈设置为的传统值:很少有程序真正需要更多,甚至适度避免在堆栈上放置大量数据。在多线程环境中,每个线程最终都有自己的堆栈:因此保持堆栈小也可以使线程更便宜。现代系统可能会将其设置得更大,因为它们为每个进程提供了大量的地址空间。
在64位系统上,为堆栈使用50位的地址空间相对容易(远远超过你的计算机目前可以处理的:谷歌数据中心处理的是pb)。但这样做的缺点是,只有在被一个进程占用了整个系统的虚拟内存之后,才会在调试时破坏堆栈。这样做的好处并不是那么大。
堆栈的大小由实现定义,而不是由c++标准公开。关于如何确定它的大小,以及如何更改它的大小,请参阅编译器文档。
c++标准没有规定当你破坏堆栈时会发生什么。一般来说,当堆栈被破坏时,您可能会遇到严重的麻烦:编写代码以便它不会发生,而不是在它发生后捕获它。
- 是,这是堆栈溢出。你得到的错误信息是平台相关的——所以如果你在不同类型的机器上运行它,你可能会看到"stack overflow"。
- 没有好的便携式方法可以做到这一点,正如这里所看到的。这是因为你没有得到一个抛出的异常,你让操作系统以任何它想要的方式杀死你的进程。
- 您的堆栈限制比可用内存小得多(堆栈通常为8-20MB)。在特定的操作系统设置中,如果确实需要更大的值,可以重新配置这个值(Solaris上的ulimit -s 100000将其设置为100MB)。但是达到堆栈限制通常意味着你做错了什么。小的堆栈限制有助于操作系统使用虚拟内存分配方案,并且是堆栈溢出的早期错误捕获器(想象一个较慢版本的代码在一两个小时内消耗所有可用内存……没有那么有趣的其他东西运行)。
- 这可能是操作系统或编译器相关的,并不是c++固有的东西。试试这个关于确定堆栈大小的各种方法的SO链接。
相关文章:
- 对象接收堆栈溢出异常 c++ 的排序向量
- 堆栈上的 C++ 访问冲突写入异常
- 主函数执行时C++堆栈溢出异常
- Hinnant的堆栈分配器和异常
- 在使用 In Order 遍历成员函数时引发异常(堆栈溢出)时出现问题
- 在 Myfile.exe 中0x00831D39时未处理的异常:0xC00000FD:堆栈溢出(参数:0x0000000
- CUDA 编程未处理的异常和堆栈溢出
- C 堆栈溢出异常,可能是由于递归引起的
- 启用优化时的堆栈指针比较异常
- throw() 函数应该总是在异常时展开堆栈并允许捕获异常还是必须调用 std::terminate ?
- std::list 和 std::vector 中的堆栈溢出异常
- c++ 的除法的其余部分出现"堆栈溢出"异常
- 如何在Visual Studio(2015)中增加堆栈尺寸的堆栈尺寸?异常代码:C00000FD
- 捕获异常后的堆栈跟踪
- 我在程序中遇到堆栈溢出异常C++
- 堆栈溢出异常中c++和c#之间的差异
- 是否可以对构造函数抛出异常的对象进行异常处理,该对象的异常处理接近其基于堆栈的代码创建
- 在 C++/STL/MFC 应用程序启动早期发生的致命异常中,是否可以信任堆栈回溯符号名称?
- 程序在函数声明时崩溃,出现未经处理的异常:堆栈溢出
- 堆栈异常处理和析构函数展开.如何使用这些信息