C指针:引发异常:读取访问冲突

时间:2018-10-08 07:36:29

标签: c

我正在用C编写一个玩Craps游戏的程序。在我的第一个掷骰之后,当我获得点(胜利)或失败时,该程序只是结束而不是调用is_win或is_loss。

但是如果它在我的第一卷中调用is_win或is_loss,则一切正常。

我相当确定这与指针pbal有关。我在调试器中收到错误消息,提示无法读取内存,也引发了异常:读取访问冲突。我对指针还很陌生,因此我假设这是问题的根本原因。

# include "header.h"

int print_menu(void) {
    int choice = 0;
    printf("\n1. Enter balance\n2. Play game\n3. Get rules\n4. End game");
    printf("\nEnter which you would like to do: ");
    scanf("%d", &choice);
    return choice;
}

void print_rules(void) { 
    printf("\nFirst Roll: If your die roll adds to 7 or 11, you win.\nIf it adds to 2, 3, or 12, you immediately lose.\nIf it adds to another number, that number becomes your 'point'");
    printf("\nSecond Roll: If your die roll adds to your point, you win. If it adds to 7, you lose.\nKeep rolling until you get one of these.\n\n");
}

int get_balance(balance) {

    printf("\nEnter how much money you would like to add (whole dollars): ");
    scanf("%d", &balance);
    return balance;
}

int prompt_bet(balance) {
    int bet = 0;
    do {
        printf("\nEnter how much you would like to bet for this game: ");
        scanf("%d", &bet);
        } while (bet > balance); //repeats until its false that bet>bal
    return bet;
}

int roll_dice(void) {
    srand((unsigned int)time(NULL));

    int enter = 1;
    printf("\nEnter a 0 to roll your dice: ");
    scanf("%d", &enter);

    int die1 = rand() % 6 + 1;
    int die2 = rand() % 6 + 1;
    int dice = die1 + die2;
    printf("You rolled a %d and a %d, with a total of %d.\n", die1, die2, dice);
    return dice;
}

int calc_first_roll(int dice, int bet, int balance, int * pbal) {
    int result0 = 0;

    if (dice == 7 || dice == 11) {
        is_win(bet, balance, pbal);
        }

    else if (dice == 2 || dice == 3 || dice == 12) {
        is_loss(bet, balance, pbal);
        }

    else {

        printf("Your point is %d", dice);
        int point = dice;

        int done = 1;
        do {
            dice = roll_dice();
            done = calc_other_rolls(point, dice, balance, bet, *pbal);


        } while (!done);


        }

    return result0;
}

void is_win(int bet, int balance, int *pbal) {

    /* the pointer *pbal is pointing to mainbalance. I had to pass it
    through everything to get it to affect mainbal the way I wanted it to.
    Think of mainbalance as the permanent memory for keeping their bets & money right,
    and int balance is just a messenger that doesn't get in the way of me trying
    to use a pointer on mainbalance. */

    *pbal = balance + bet;
    printf("You win! Your new balance is %u\n", *pbal);
}

void is_loss(int bet, int balance, int *pbal) {
    *pbal = balance - bet;
    printf("You lost. Your new balance is %u\n", *pbal);
}

int calc_other_rolls(int point, int dice, int balance, int bet, int *pbal) {
    int done = 0;
    if (dice == 7) {  //Goes straight to is_l / is_w instead of looping back to calc_first

        is_loss(bet, balance, *pbal);
        done = 0;
    }

    else if (dice == point) {
        is_win(bet, balance, *pbal);
        done = 0;
    }

    else {
        done = 0;

    }
    return done;
}




# include "header.h"

int main(void) {
    int mainbalance = 0;
    int choice = 0;
    int *pbal = &mainbalance;

    do {
        choice = print_menu();

        if (choice == 1) {
            mainbalance = get_balance();
            printf("Your balance is: %d\n", mainbalance);
            choice = 8; //reprints menu
            }

        if (choice == 3) {
            print_rules();
            choice = 8;
            }

        if (choice == 4)
            exit(1);

        if (choice == 2) {

            int bet = prompt_bet(mainbalance);
            int dice = roll_dice();
            int x = calc_first_roll(dice, bet, mainbalance, pbal);



            choice = 8;

            }

    } while (choice > 4 || choice < 1); //keeps running code until test becomes false.


    return 0;
}

1 个答案:

答案 0 :(得分:0)

在本节中:

if (dice == 7) {  //Goes straight to is_l / is_w instead of looping back to calc_first

    is_loss(bet, balance, *pbal);
    done = 0;
}

else if (dice == point) {
    is_win(bet, balance, *pbal);
    done = 0;
}

您没有传递is_lossis_win指针,而是传递了pbal所指向的整数值。声明之外的*始终取消引用。

因此,如果calc_other_rolls获得int *pbal作为参数,并且您想将其传递给采用int *的另一个函数,则应该执行func(pbal)而不是func(*pbal) ,因为第二个参数传递的是值而不是指针。

编辑:正如@hollow指出的那样,如果启用警告,则编译器会对此进行标记,因此请使用它们。