c++ - 递归函数引起的栈溢出

标签 c++ function recursion stack-overflow

我是 C++ 的初学者。昨天我读到递归函数,所以我决定自己写一个。这是我写的:

int returnZero(int anyNumber) {
    if(anyNumber == 0)
        return 0;
    else  {
        anyNumber--;
        return returnZero(anyNumber);
    }
}

当我这样做时:int zero1 = returnZero(4793);,它会导致堆栈溢出。但是,如果我将值 4792 作为参数传递,则不会发生溢出。

关于原因有什么想法吗?

最佳答案

无论何时调用函数,包括递归调用,返回地址和参数通常都会被推送到 call stack 上.堆栈是有限的,因此如果递归太深,您最终会耗尽堆栈空间。

令我吃惊的是,在您的机器上只需要调用 4793 次就可以溢出堆栈。这是一个非常小的堆栈。相比之下,在我的计算机上运行相同的代码在程序崩溃之前需要大约 100 倍的调用次数。

堆栈的大小是可配置的。在 Unix 上,命令是 ulimit -s

假设函数是tail-recursive ,一些编译器可能能够通过将其转换为跳转来优化递归调用。一些编译器可能会进一步采用您的示例:当要求进行最大优化时,gcc 4.7.2 将整个函数转换为:

int returnZero(int anyNumber) {
  return 0;
}

这恰好需要两条汇编指令:

_returnZero:
        xorl    %eax, %eax
        ret

非常整洁。

关于c++ - 递归函数引起的栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15976333/

相关文章:

recursion - 用尾递归解决 "n-rooks"

java - 使用递归方法通过控制流中断 Java 循环的迭代

recursion - 递归在 Verilog 中是如何工作的?

c++ - C++中的删除操作

c++ - 不确定为什么对象是本地的而不是引用的

c - C 中的 Brick-Breaker - 递增砖行问题

function - Swift、数学函数和协议(protocol)

c - 当我尝试运行它时,程序崩溃了,我不知道为什么

c++ - 通过非 unicode 代码读取 UTF-8 Unicode 文件

c++ - 科学计数法 C++ 中的字符串到双重转换