为什么我的递归函数会导致分段错误?

时间:2017-08-12 20:49:54

标签: c recursion

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

当我尝试访问无法访问的内存时,应该发生分段错误,但在此程序中,我不会尝试访问任何无法访问的内存。

#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;
}

2 个答案:

答案 0 :(得分:2)

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

堆栈有一定的大小。它可能很大,但它是有限的。在递归中,您始终从内部调用相同的函数。如果这种情况发生的次数太多,你将会溢出堆栈&#34; - 也就是说,试着推动&#34;堆栈已经满了的更多信息,这意味着在地址超过堆栈的末尾 - 您可能无法访问的内存。 (如果你有权访问它,你可能会覆盖你的一个变量或其他变量。)

如果你已经进行了足够的递归,则必须从函数返回而不再调用它。可能在你的n == 1&#34; if&#34;。

答案 1 :(得分:-2)

在递归的基本情况下,你没有任何return语句所以你的代码会持续无限时间(超出时间限制),你应该尝试这样:

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