为什么这段代码会产生分段错误?

时间:2015-10-10 02:08:04

标签: c segmentation-fault

我正在编写一个程序,其目标是生成一个随机的三位数字,并让用户对其进行10次猜测。如果他们在正确的位置猜测正确的数字,则认为是“命中”。如果他们猜测正确的数字,但它在错误的位置,则认为是“匹配”。例如,如果要猜测的数字是123,并且您输入329,那么2将是命中,3将是匹配。到目前为止,我的代码如下所示:

#include <stdio.h>
#include <time.h>

#define MIN 100
#define MAX 999

int main()
{
    //Declare variables
    int userDig1 = 0, userDig2 = 0, userDig3 = 0, randDig1 = 0, randDig2 = 0, randDig3 = 0, guesses = 0;

    //Generate random three digit number
    srand(time(NULL)); //seed
    randDig1 = rand() % ((MAX + 1) - MIN) + MIN; //corresponds to the first digit
    randDig2 = rand() % ((MAX + 1) - MIN) + MIN; //corresponds to the second digit
    randDig3 = rand() % ((MAX+ 1 ) - MIN) + MIN; //corresponds to the third digit

    //A for loop that keeps track of the number of guesses
    for (guesses = 1 ; guesses <= 10 ; guesses++)
    {
        //Store user's guess into the appropriate variables
        printf("Enter guess number %d:\n", guesses);
        scanf("%d%d%d\n", userDig1, userDig2, userDig3);

        //Check the user's digits against the actual digits
        if (userDig1 == randDig1) //if first user digit = first actual digit
        {
            printf("Number %d is a hit!\n", userDig1);
        }
        if (userDig2 == randDig2) //if second user digit = second actual digit
        {
            printf("Number %d is a hit!\n", userDig2);
        }
        if (userDig3 == randDig3) //if third user digit = third actual digit
        {
            printf("Number %d is a hit!\n", userDig3);
        }
        if (userDig1 == randDig1 && userDig2 == randDig2 && userDig3 == randDig3) //if all 3 user digits = all 3 actual digits
        {
            printf("Congratulations, you guessed the number %d%d%d\n", userDig1, userDig2, userDig3);
            break;
        }
        if (userDig1 == randDig2 || userDig1 == randDig3) //if first user digit = second or third actual digit
        {
            printf("Number %d is a match!\n", userDig1);
        }
        if (userDig2 == randDig1 || userDig2 == randDig3) //if second user digit = first or third actual digit
        {
            printf("Number %d is a match!\n", userDig2);
        }
        if (userDig3 == randDig1 || userDig3 == randDig2) //if third user digit = first or second actual digit
        {
            printf("Number %d is a match!\n", userDig3);
        }
        else //if none of the user's digits are matches or hits
        {
            printf("None of the digits you entered are matches or hits. Guess again.\n");
        }
    }

    printf("Game over! You failed to guess the correct number.\n");
}

编译并运行后,我输入第一个猜测后出现分段错误错误。

现在我知道为什么发生分段错误。这意味着您正在尝试访问您无权访问的内存/值(沿着这些行)。但在这种特殊情况下,我不明白会导致这种情况发生的原因。如果我不得不猜测,我会说它与我的scanf语句有关,我试图通过将每个数字解释为一个单独的整数来“提取”数字。我知道提取数字的数学方法(mod乘10,除以10),因为我在不同的程序中使用了这个概念,但没有使用循环逻辑。我试图在这里使用循环来提取数字,但我还没有找到适用于所有数字的方法。所以最终,我的问题是什么,我该怎么做才能解决它?

感谢任何和所有帮助。

(另外,我知道我在这里有一些错误的格式,例如break语句位于所有if语句的中间。我还将此代码移动到一个单独的函数中,以便用户可以再次播放而无需关闭程序并重新打开它。)

1 个答案:

答案 0 :(得分:2)

因为您将整数传递给scanf(),其中指向了一个指针。

从整数中生成指针是未定义的行为,您应该传递值的地址,因为它们将由函数修改,在这种情况下使用scanf()的正确方法是

if scanf("%d%d%d*%c", &userDig1, &userDig2, &userDig3) == 3)
    input_is_correct();
else
    input_is_bad();

请注意,在您的情况下,您将0传递给scanf(),它可能会尝试取消引用(void *) 0x00NULL。这也是未定义的行为。

使用不是&运算符变量地址的指针或malloc() / calloc() / realloc()的返回值通常是未定义的行为