我有以下递归方法。我收到错误堆栈溢出。它停在 -9352。我的问题是,堆栈溢出是否与无限循环相同?因为这会一直调用自己。
但是如果我使用 while、until、do 等进行无限循环,它不会给我相同的堆栈溢出错误。它会一直运行,直到我的系统内存不足。
这是使用 Ruby
def recursion(n)
print n
recursion(n-1)
end
recursion(3)
输出:
3
2
1
0
.
.
.
-9352 stack overflow stops
递归和循环是可以用不同方式解决类似问题的技术(如评论中所述,它们是图灵等价的,但这不是我的领域)。
每个函数调用都会向调用堆栈添加一个帧。这需要额外的内存,并且随着调用链的深入,它需要更多的内存,直到超过某个限制,这会使您的堆栈溢出
并使您的程序崩溃。
您的递归 代码向调用堆栈添加越来越多的帧,并且在给定有限内存量的情况下,将导致它溢出。您需要一些方法来告诉递归何时停止,并在内存耗尽之前这样做。这种情况等同于数学归纳法中的base case
,因此通常这样称呼。
注释中指出的另一个选项是利用 Tail call优化,替换堆栈中的当前帧,因此可以防止堆栈溢出。
您的迭代解决方案只需要固定数量的内存。
只有计数器或其他预定义变量的值会发生变化,因此不会产生任何内存开销。
如果不限制输出,理论上它可以无限期地继续下去,但其他一些耗尽或错误很可能会终止它。但是,这不会是循环本身使用的变量所消耗的内存。