【问题标题】:Trouble resolving stack overflow error [closed]解决堆栈溢出错误的麻烦[关闭]
【发布时间】:2015-08-31 17:05:58
【问题描述】:

我收到以下代码的堆栈溢出错误:

void f {
    f();
}

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

知道为什么吗?

【问题讨论】:

  • "堆栈溢出问题通常是由损坏的注册表项引起的。" LOL
  • 这是没有基本情况的递归 -> 无限循环
  • 这是一个巨魔,我敢打赌... :-)
  • 这个问题的每一部分都令人费解。您编写了一个毫无意义的程序,并且神奇地期望一些随机的通用配方使您的程序有意义?
  • @Carlton 是的,这很有趣。你笑了。现在,回到严肃的问题,好吗?

标签: c++ c


【解决方案1】:

问题在于函数f 调用自身。这会创建一个无限循环,耗尽堆栈并使程序崩溃。

你期望这个函数应该做什么?

void f {
    f();
}

【讨论】:

    【解决方案2】:

    第一个函数 (f) 是一个递归函数。每次调用f 时,都会再次调用函数f。这会导致创建新的堆栈帧。现在,没有退出条件,因此f 将被一遍又一遍地调用。最终,您将用完堆栈帧,并且会发生 stackoverflow。

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

    1.使用尾递归优化。
    为此,如果使用 gcc,请使用 -O2 进行编译。因此,请使用以下命令。
    gcc -O2 $filename -o $executableName 这将优化 f 的尾递归,并从本质上创建一个无限循环,而不是在程序集中创建跳转和链接。
    请注意,尾递归优化在您在函数中执行的最后一件事是调用另一个函数(即,如果您执行的最后一件事导致不再需要堆栈帧)时起作用。

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

    【讨论】:

    • 这个答案 (1) 仅在您认为 OP 更喜欢锁定并必须手动杀死的程序而不是因堆栈溢出而崩溃的程序时才有意义。我不明白你为什么建议这个。
    • @ChrisBeck 好吧,我假设 OP 将代码作为示例发布。也就是说,在f 中递归调用f 之前,OP 可能会有一些代码,包括退出条件。在这种情况下,如果递归调用在达到退出条件之前可能会超过堆栈帧限制,尾递归就会变得有用。
    猜你喜欢
    • 2020-01-11
    • 1970-01-01
    • 2022-01-05
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 2019-02-16
    • 2011-09-10
    相关资源
    最近更新 更多