如何创建无限递归会抛出堆栈溢出异常?

Mil*_*avi 2 c++ stack-overflow stack callstack exception

我正在尝试使用以下程序创建堆栈溢出运行时异常:

void f(int a) {
  cout << a << ", ";
  f(++a);
}

int main () {
  f(0);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行此程序时,我的计算机运行大约261824 call stack然后command terminated发生运行时错误.现在我想知道:

  1. 这是堆栈溢出的一个很好的例子吗?如果是,为什么command terminated会出现错误?
  2. 我怎么能try,catch堆栈溢出异常?
  3. 我有很多自由记忆; 为什么我的堆栈不会占用我所有的记忆?
  4. 如何确定堆栈的大小与我的对应call stack

Yak*_*ont 6

这些都是实现细节.从技术上讲,C++实现不需要堆栈,只需要自动存储.至少有一个C实现在堆中使用了链接列表(好吧,根据我的理解,这是一个奇怪的系统),用于自动存储.

但是,通常,堆栈是内存地址空间的连续区域,该进程仅保留用于存储自动变量和调用帧.它必须在其他任何事情发生之前保留,因为它必须是连续的,并且如果为了另一个目的分配了一些内存块,则堆栈将无法增长.

如果你想将整个内存地址空间用于堆栈,那么堆就没有空间(也就是免费商店).所以堆栈不使用所有内存......

1 MB是将堆栈设置为的传统值:很少有程序真正需要更多,甚至可以适度避免在堆栈上放入大量数据.在多线程环境中,每个线程最终都有自己的堆栈:因此保持较小也会使线程更便宜.现代系统可能将其设置得更大,因为它们为每个进程提供了大量的地址空间.

在64位系统上,使用50位地址空间相对容易(比计算机目前可以处理的方式更多:谷歌数据中心处理数PB).但是这样做的缺点是,只有整个系统的虚拟内存被一个进程抓取后,你才会在调试时放弃堆栈.这方面的好处并不是那么大.

堆栈的大小是实现定义的,并且不是由C++标准公开的.请参阅编译器文档,了解如何确定其大小以及如何更改其大小.

C++标准没有规定当你炸掉堆栈时会发生什么.通常,当堆栈被烧毁时,您可能会遇到严重问题:编写代码以使其不会发生,而不是在它发生后捕获它.