2015-08-31 103 views
-7

我正在用下面的代码堆栈溢出错误:故障解决堆栈溢出错误

void f { 
    f(); 
} 

int main() { 
    f(); 
    return 0; 
} 

任何想法,为什么?

+5

“*堆栈溢出问题通常是由损坏的注册表项引起的。*”* LOL * – alk

+0

这是没有基本情况的递归 - >无限循环 – sam

+2

这是一个巨魔,我打赌...... :-) – alk

回答

2

问题是功能f自己调用。这会造成无限循环,导致堆栈崩溃并导致程序崩溃。

你期待这个功能应该做什么?

void f { 
    f(); 
} 
1

第一个函数(f)是一个递归函数。在每次拨打f时,将再次调用功能f。这会导致创建新的堆栈帧。现在,没有退出条件,因此f将被重复调用。最终,您将用完堆栈框架,并发生stackoverflow。

有两种方法可以解决这个问题。

1.使用尾递归优化。
为此,如果使用gcc,请使用-O2进行编译。所以,使用下面的命令。
gcc -O2 $filename -o $executableName 这将针对尾递归优化f,本质上创建一个无限循环,而不是在程序集中创建跳转和链接。
请注意,尾递归优化只有当你在函数中做的最后一件事情是调用另一个函数(也就是说,如果你最后一件事情导致不再需要堆栈帧),它将起作用。

2.添加退出条件
这取决于你想要做什么。假设你想递归三次。然后,您需要在每次通话时将参数传递给f。然后,在f中,检查退出条件是否为true。如果是这样,只需return。如果不是,则用一个新参数再次调用f

+1

这个答案(1)只有在你认为OP会选择一个锁定的程序并且必须手动杀死一个崩溃的程序时才有意义。我不明白你为什么这么说。 –

+1

@ChrisBeck好吧,我假设OP公布了代码作为例子。也就是说,在递归调用'f'中的'f'之前,OP可能会有一些代码,包括退出条件。在这种情况下,如果递归调用在达到退出条件之前可能超过堆栈帧限制,则尾递归变得有用。 – nehcsivart