【问题标题】:Why does this recursive function crash?为什么这个递归函数会崩溃?
【发布时间】:2014-10-07 02:36:13
【问题描述】:
    int g(int n) {
        int x = g(n - 1);
        if (x > 0) {
            return x + 1;
        } else {
            return 1;
        }
    }

我的猜测是它与函数的第一行有关...但我不确定为什么会这样。

【问题讨论】:

  • 看起来你进入了无休止的递归。通常,您会检查一个或多个基本情况,如果不是,则进行递归调用。
  • g(n) 正在调用 g(n-1),无论 n 的值如何,并且永无止境。

标签: c++ crash segmentation-fault


【解决方案1】:

如果函数只是这样说的:

int g(int n) {
    return g(n - 1);
}

那么你显然不会期望它工作,而是继续递归,直到你用完堆栈空间并且程序崩溃。通过将递归放在函数中的退出条件之前,您基本上就是在这样做。

您应该重写该函数,使其在再次调用g() 之前执行退出测试

【讨论】:

  • 好的,那么基本情况必须在递归调用之前定义?
  • @user3019324:否则 C++ 将如何达到它?
【解决方案2】:

如果您通过诸如gdb 之类的调试器运行它,您应该会看到它实际上从未退出。

Program received signal SIGSEGV, Segmentation fault.
0x00000000004004de in g (n=-240246) at test.c:10

test.c:10 在我的例子中是你的int x = g(n - 1); 行,它只是不断地被一遍又一遍地调用。

【讨论】:

    【解决方案3】:

    因为函数的第一行调用完全相同的函数,'return' 永远不会被执行。因此它是一个无限循环,直到它“崩溃”。

    如果我们要评估它: g(20):调用g(19):调用g(18)等等。

    递归调用通常在函数结束时被调用,或者至少在确保递归不是无限的评估之后(例如在您的示例代码中)。

    【讨论】:

    • 所以'if'语句甚至永远不会被查看?它会在第一行崩溃吗?
    • 没错,它永远不会超过第一行。尝试在if: 上运行带有断点的调试器:这永远不会命中。在 g(n-1) 调用上运行带有断点的调试器将不断受到命中。
    猜你喜欢
    • 2022-01-13
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多