简体   繁体   English

为什么我的递归程序给我一个分段错误?

[英]Why is my recursive program giving me a segmentation fault?

I keep on getting a segmentation fault when I run my program.当我运行我的程序时,我不断收到分段错误。 Segmentation faults are generally supposed to happen when the program tries to access memory which the computer can't physically address.当程序尝试访问计算机无法物理寻址的内存时,通常应该会发生分段错误。 I can't pinpoint where the problem lies.我无法确定问题出在哪里。

Edits: I changed added the & when scanning the variables but that does not fix the problem of the segmentation fault编辑:我更改了扫描变量时添加了 & 但这并不能解决分段错误的问题

Here is my code:这是我的代码:

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


    void userEnter(int*pattern, int n);
    void print( int * s, int n);
    void recurs( int * s, int * a, int n, int wpegs, int bpegs);
    bool Done (int*s);
    bool bPegs(int*a ,int*s, int bpegs, int wpegs, int n);
    bool wPegs(int* modcom, int* modoriginal, int*s, int wpegs, int w);
    void change(int*modoriginal, int*modcom, int i, int k, int w);

    int main(void)
    {
        int i, n, bpegs, wpegs;

        printf("Enter the pattern length: ");
        scanf("%d",&n);
        int *a = (int*)malloc((n)*(sizeof(int)));
        printf("Input the guess pattern: ");
        int pattern[n];
        userEnter(pattern, n);  
        printf("Enter the number of black pegs in the feedback: ");
        scanf("%d",&bpegs);
        printf("Enter the number of white pegs in the feedback: ");
        scanf("%d",&wpegs);
        printf("The possible key patterns are: ");
        for(i=0; i<=n-1; i++)
        {
            a[i]=0;
        }
        print(a, n);
        recurs(a, pattern, n, wpegs, bpegs);

    }

    void userEnter(int*pattern, int n)
    {
        char input[n];
        scanf("%s",&input);

        int i;
        for(i = 0; i < n-1; i++)
        {
            pattern[i] = input[i]-65;
        }
    }

    void print( int * s, int n)
    {
        int i; 
        printf( "\n" );
        for( i = n-1; i >= 0; i-- )
        {
            printf( "%c", ( s[ i ] + 65 ) );
        }
    }

    void recurs( int * s, int * a, int n, int wpegs, int bpegs)
    {

        int i;

        if(Done(s))
        {
            print( s, n);
            printf( "\nAccomplisshed!\n" );
        }

        else{
            s[ 0 ] += 1;
            for( i = 0; i < n-1; i++ )
            {
                if( s[ i ] == 6 ){
                    s[ i ] = 0;
                    s[ i + 1 ] += 1;
                }
            }
            if(bPegs(a ,s, bpegs, wpegs, n))
            {
            print( s, n);
            }
            recurs(s, a, n, wpegs, bpegs);
        }
    }

    bool Done (int*s)
        {
            int i;
            bool done=true;
            for (i=0;i<=11;i++)
            {
                if(s[i]!=5)
                {
                    done=false;
                }
            }
            return done;
        }


    bool bPegs(int*a ,int*s, int bpegs, int wpegs, int n)
    {
        int i,j,c=0;
        bool d = false;
        for(i=0; i<n-1; i++)
        {
            if(a[i]==s[i])
            {
                c++;
            }
        }
        int x =n-c;
        int* modcom; 
        int*modoriginal;
        modcom=(int*)malloc((x)*(sizeof(int)));
        modoriginal=(int*)malloc((x)*(sizeof(int)));
        int w=0;
        for(j=0; j<n-1; j++)
        {
            if(a[j]!=s[j])
            {
                modcom[w]=s[j];
                modoriginal[w]=a[j];
                w++;
            }       
        }
        if(c==bpegs)
        {
            d = wPegs(modcom, modoriginal, s, wpegs, w);
        }

        return d;

    }

    bool wPegs(int*modcom, int*modoriginal, int*s, int wpegs, int w)
    {
        int i, k, count=0;
        for(i=0; i<=w; i++)
        {
            for(k=0; k<=w; k++)
            {
                if (modoriginal[i]==modcom[k])
                {
                    count++;
                    change(modoriginal, modcom, i, k, w);
                }
            }
        }
        if(wpegs==count)
        {
            return true;
        }
        else
        {
            return false;
        }

    }

    void change(int*modoriginal, int*modcom, int i, int k, int w)
    {
        int c, o;
        for(c=i-1; c<w-1; c++)
        {
            modoriginal[c]=modoriginal[c+1];
        }
        for(o=k-1;o<w-1;o++)
        {
            modcom[o]=modcom[o+1];
        }
    }

Because you are not passing arguments to scanf properly, as reported by the compiler:因为您没有正确地将参数传递给scanf ,正如编译器所报告的那样:

13421173.c:25: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’
13421173.c:25: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’
13421173.c:27: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’
13421173.c:27: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’

Correct usage looks like:正确的用法如下:

scanf("%d", &bpegs);

I haven't checked all the code but you should change我还没有检查所有的代码,但你应该改变

scanf("%d",bpegs);
printf("Enter the number of white pegs in the feedback: ");
scanf("%d",wpegs);

to

scanf("%d",&bpegs);
printf("Enter the number of white pegs in the feedback: ");
scanf("%d",&wpegs);

ie pass pointers to the ints you want scanf to write to即传递指向您希望 scanf 写入的整数的指针

The arguments for scanf are a format and a pointer to a variable of the same type of format. scanf的参数是一个格式和一个指向相同类型格式的变量的指针。 In the case of integers %d requiers &d where d is of type int .对于整数%d需要 &d ,其中 d 是int类型。 For a string, like input in your function userEnter() , %s rquires a type char* , input is an array, that means input without de braces is already a pointer so you only write对于字符串,如函数userEnter()输入, %s需要一个类型char* ,输入是一个数组,这意味着没有大括号的输入已经是一个指针,所以你只能写

scanf("%s",input);

Also you should check the limits in your for cicles.此外,您应该检查您for cicle 中的限制。 For instance in bPegs() you are allocating memory for modcom and modoriginal of size x = n - c , and in the next for cicle your limit goes to n-1, this creates a segmentation fault unless c = 1.例如,在bPegs()您正在为大小为x = n - c 的modcom 和 modoriginal 分配内存,而在下一个 cicle 中,您的限制为 n-1,除非 c = 1,否则这会产生分段错误。

Something like:就像是:

scanf("%d",bpegs);

Makes an implicit cast from int to int pointer, so that the read integer will be written in a some random address.This random address depends on the value of bpegs, which wasn't initialized.If you used scanf plenty times, then you have to correct all these errors, and pass the address of the value to change, not the value.进行从 int 到 int 指针的隐式转换,以便读取的整数将写入某个随机地址。该随机地址取决于未初始化的 bpegs 的值。如果您多次使用 scanf,那么您有纠正所有这些错误,并传递要更改的值的地址,而不是值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM