【问题标题】:Why does my recursive function cause a segmentation fault?为什么我的递归函数会导致分段错误?
【发布时间】:2017-08-13 08:56:20
【问题描述】:

在下面的代码中,我试图解决河内塔问题。为什么会出现分段错误(核心转储)?

当我尝试访问无法访问的内存时会出现分段错误,但在此程序中我没有尝试访问任何无法访问的内存。

#include <stdio.h>
#include <stdlib.h>

void steps(int n, int t, int p)
{
    int i, k = 6 - (p + t);

    if (n == 1) {
        printf("%d-->%d\n", n, t);
    }

    for (i = 0; i < 2; ++i) {
        if (i == 0) {
            steps(n - 1, k, p);
            printf("%d-->%d\n", n, t);
        } else {
            steps(n - 1, t, k);
        }
    }
}

int main()
{
    int n;
    printf("Enter the value of n: ");
    scanf("%d", &n);
    steps(n, 3, 1);
    return 0;
}

【问题讨论】:

  • 需要递归停止条件。
  • 好的,所以我必须将其余代码包装在 else 中!谢谢
  • 我拒绝了编辑,因为没有任何改进。
  • 标题误导性很强,请编辑。

标签: c recursion


【解决方案1】:

您正在访问您无法访问的内存。它在代码中并不明显(如悬空指针)。递归很棘手;你可以很容易地溢出堆栈。当你进入一个函数时,堆栈存储的信息(寄存器或参数地址,在调用函数和被调用函数中使用的寄存器的保存值,以及一个返回指针(当你完成函数时跳转到哪里)。

堆栈有一定的大小。它可能很大,但它是有限的。在递归中,您不断地从自身内部调用相同的函数。如果这种情况发生太多次,您将“溢出堆栈” - 也就是说,尝试在堆栈已满时将更多信息“推送”到堆栈上,这意味着在一个地址超过堆栈末尾 -- 您可能无法访问的内存。 (如果您确实可以访问它,您可能会覆盖您的某个变量或类似的变量。)

当你递归的足够远时,你必须从你的函数返回而不再次调用它。可能在您的 n==1 “如果”中。

【讨论】:

    【解决方案2】:

    在递归的基本情况下,您没有任何 return 语句,因此您的代码会无限运行(超出时间限制),您应该尝试这样:

    if(n==1)
    {
        printf("%d-->%d\n", n, t);
        return ;
    }
    

    【讨论】:

    • 没有时间限制,这不是段错误
    • 它不会持续无限时间。它会导致堆栈溢出。
    • 是的,没有return语句,会导致堆栈溢出。我说的对吗?
    • 虽然它的作品,但我建议 Rahul 阅读Segmentation fault 以了解有关 Seg-Fault 的一些重要信息。
    猜你喜欢
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2020-04-15
    相关资源
    最近更新 更多