由递归函数引起的堆栈溢出

cha*_*les 8 c++ stack-overflow recursion function

作为C++编程和计算机系统架构的初学者,我还在学习C++的基础知识.昨天我读到了递归函数,所以我决定写自己的,这是我写的:(非常基础的)

int returnZero(int anyNumber) {
    if(anyNumber == 0)
        return 0;
    else  {
        anyNumber--;
        return returnZero(anyNumber);
    }
Run Code Online (Sandbox Code Playgroud)

}

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

任何想法为什么?

NPE*_*NPE 26

无论何时调用函数(包括递归),返回地址和参数通常都会被推送到调用堆栈.堆栈是有限的,所以如果递归太深,你最终会耗尽堆栈空间.

让我感到惊讶的是,你的机器只需要4793次调用即可溢出堆栈.这是一个非常小的堆栈.通过比较,在我的计算机上运行相同的代码需要在程序崩溃之前调用大约100倍的调用.

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

鉴于该函数是尾递归的,一些编译器可能能够通过将其转换为跳转来优化递归调用.有些编译器可能会更进一步:在要求进行最大优化时,gcc 4.7.2将整个函数转换为:

int returnZero(int anyNumber) {
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这需要两个装配说明:

_returnZero:
        xorl    %eax, %eax
        ret
Run Code Online (Sandbox Code Playgroud)

很简约.

  • @Fernando:他说失败了4793,适用于4792. (5认同)

Ósc*_*pez 5

您刚刚达到了系统调用堆栈的大小限制,这就是正在发生的情况。由于某些原因,系统中的堆栈很小,4793 个函数调用的深度相当小。