有一个函数可以无限地递归调用自己。
这个函数也有一些参数。
对于每个函数调用,参数和返回地址都被压入堆栈。
对于每个进程,都有固定大小的堆栈空间,不能像堆一样动态增长。 我猜每个线程也有自己的堆栈。
现在如果一个函数被无限地递归调用并且进程耗尽堆栈空间,会发生什么?
程序会崩溃吗? OS会处理这种情况吗? 有4GB的地址空间,所以为什么操作系统无法做些什么来增加堆栈大小。
答案 0 :(得分:6)
在UNIX和兼容中,该进程将终止投掷 SIGSEGV
或 SIGSTKFLT
信号。
在Windows中,该过程将被终止,抛出异常 STATUS_STACK_OVERFLOW
。
答案 1 :(得分:2)
这与语言无关 - 它在很大程度上取决于语言/平台。
在C#(或任何.NET语言)中,您将获得StackOverflowException
,从.NET 2.0开始无法捕获并将导致该过程失效。
在Java(或任何JVM语言)中,您将获得StackOverflowError
(specified here)。
我将把它留给处理其他语言和平台的其他答案:)
答案 2 :(得分:1)
至少对于C ++来说,你将处于“未定义行为”的领域 - 有点像暮光之城,任何事情都可能发生。
如果递归是无限的,增加堆栈大小有什么好处呢?最好早点失败。
答案 3 :(得分:1)
根据语言,您将获得异常(例如在Java中)或程序将崩溃(在C,C ++中)。
通常堆栈相对较小,因为这样就足够了,堆栈溢出会发出错误信号。在Java中,如果必须,可以使用命令行选项增加堆栈空间。
另请注意,函数式语言通常将尾递归编译为循环,在这种情况下不使用堆栈空间。
答案 4 :(得分:0)
典型的Unix结果将是分段错误。不了解Windows。
答案 5 :(得分:0)
是的,你的程序会崩溃。除了防止你的错误代码损坏其他进程(它已经在做)之外,操作系统无法“处理这种情况”。操作系统无法知道你真正想要你的程序要做什么,而不是你告诉它做什么。
答案 6 :(得分:0)
有很多答案会发生什么,但我想提一下非常简单的解决方案:
只需使用图灵机,然后让代码运行即可。它将有足够的空间。
答案 7 :(得分:-1)
该程序将崩溃。通常堆栈受操作系统的限制,以便在消耗所有可用内存之前捕获这样的错误。在Linux上,用户可以通过在shell中发出limit
命令来更改堆栈大小。