我是 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/