本文介绍了由递归函数引起的堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Being a beginner to C++ programming and computer systems architecture, I'm still learning the basics of C++. Yesterday I read about recursive function, so I decided to write my own, here's what I wrote : (very basic)

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

}

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

And when I do this : int zero1 = returnZero(4793 ); it causes a stack overflow, however, if I pass the value 4792 as parameter, no overflow occurs.

有什么想法?

推荐答案

每当你调用一个函数,包括递归,返回地址,通常参数被推送到。堆栈是有限的,所以如果递归太深,你最终会耗尽堆栈空间。

Whenever you call a function, including recursively, the return address and often the arguments are pushed onto the call stack. The stack is finite, so if the recursion is too deep you'll eventually run out of stack space.

令我惊讶的是,它只需要4793次调用溢出堆栈。这是一个相当小的堆栈。作为比较,在我的计算机上运行相同的代码在程序崩溃之前需要大约100倍的调用。

What surprises me is that it only takes 4793 calls on your machine to overflow the stack. This is a pretty small stack. By way of comparison, running the same code on my computer requires ~100x as many calls before the program crashes.

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

The size of the stack is configurable. On Unix, the command is ulimit -s.

假设函数,一些编译器可能能够通过将其转换为跳转来优化递归调用。一些编译器可能会更进一步:当要求最大优化时, gcc 4.7.2 将整个函数转换为:

Given that the function is tail-recursive, some compilers might be able to optimize the recursive call away by turning it into a jump. Some compilers might take your example even further: when asked for maximum optimizations, gcc 4.7.2 transforms the entire function into:

int returnZero(int anyNumber) {
  return 0;
}

这需要两个汇编指令:

_returnZero:
        xorl    %eax, %eax
        ret

很整洁。

这篇关于由递归函数引起的堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:46