使用malloc将地址分配给NULL指针会使程序冻结吗?这可能是非常基本的?

时间:2011-12-06 15:21:08

标签: pointers malloc

这是我的德州老扑克计划的代码:

我已经尝试了几个小时的调试,并且到处寻找!我对指针和使用malloc的知识可能有一些非常基本的缺陷,但我不知道为什么会这样:

程序编译正常并且运行正常,直到它到达malloc函数,试图为卡片变量卡* individualhand分配一个内存地址。在确认它之前的printf if语句是一个NULL指针并且可以被分配。

还包括其他一些功能。打印手(打印扑克牌和非法牌(检测非法卡输入)我省略了。

这可能是很多代码,但我觉得答案非常简单

错误发生在handget函数中,大约是代码的一半:

int hander(cards **handPtr,int counter) {
    int i, nr_of_cards = 2;
    char rawsuit, rawcard[4];

    if(counter==0){
        // allocate the required amount of memory for your cards
        (*handPtr) = (cards *) malloc(nr_of_cards * sizeof(cards));
    }
    // ask for the cards
    for (i=0; i<nr_of_cards; i++) do {

        scanf("%3s", &rawcard);

        rawsuit = rawcard[0]; 

        if (rawcard[1]=='1') {
            if (rawcard[2]=='0') {
                (*handPtr)[i].value = ten;
            } else {
                (*handPtr)[i].value = zero;
            }
        } else if (rawcard[1]=='2') {
            (*handPtr)[i].value = two;
        } else if (rawcard[1]=='3') {
            (*handPtr)[i].value = three;
        } else if (rawcard[1]=='4') {
            (*handPtr)[i].value = four;
        } else if (rawcard[1]=='5') {
            (*handPtr)[i].value = five;
        } else if (rawcard[1]=='6') {
            (*handPtr)[i].value = six;
        } else if (rawcard[1]=='7') {
            (*handPtr)[i].value = seven;
        } else if (rawcard[1]=='8') {
            (*handPtr)[i].value = eight;
        } else if (rawcard[1]=='9') {
            (*handPtr)[i].value = nine;
        } else if (rawcard[1]=='J') {
            (*handPtr)[i].value = jack;
        } else if (rawcard[1]=='Q') {
            (*handPtr)[i].value = queen;
        } else if (rawcard[1]=='K') {
            (*handPtr)[i].value = king;
        } else if (rawcard[1]=='A') {
            (*handPtr)[i].value = ace;
        } else {
            (*handPtr)[i].value = zero;
        }

        switch (rawsuit) {
            case 'h':
                (*handPtr)[i].suit = hearts; 
                break;
            case 'd':
                (*handPtr)[i].suit = diamonds;
                break;
            case 'c':
                (*handPtr)[i].suit = clubs;
                break;
            case 's':
                (*handPtr)[i].suit = spades;
                break;
            default:
                (*handPtr)[i].value = zero;
        }
    } while (!islegal(*handPtr, i+1));

    return nr_of_cards;
}

int handget(cards **playerhand,cards *thishands, int handsize) {

    cards *player,*individualhand=NULL;
    int i,playerhandsize=2,j=0,nr_players,phandsize,counter=0, individualhandsize;

    printf("Please enter the number of players: ");
    scanf("%d",&nr_players);

    (*playerhand) = (cards *) malloc(((playerhandsize*nr_players)*sizeof(cards))+(handsize*sizeof(cards)));

    handcat(playerhand,thishands,handsize);

    for (i=1;i<=nr_players;i++){

        do {
            printf("Please enter the cards for player %d: ",i);
            phandsize = (i*hander(&player,counter))+handsize;
            playerflopcat(playerhand,player,j,phandsize,handsize);
            counter++;
        } while (!islegal(*playerhand, phandsize));
        j++;

    }
    printf("The cards on the table are:\n");
    printhand(thishands,handsize);

    for (i=1;i<=nr_players;i++){    
        printf("The private cards of player %d are ",i);
        printhand(*playerhand+(handsize+(2*(i-1))),2);
    }

    for (i=1;i<=nr_players;i++){    

        individualhandsize = handsize + playerhandsize;
        printf("individualhandsize=%i\n",individualhandsize);

        if(individualhand==NULL){ 
        printf("individualhand EQUALS NULL!");
        }

        individualhand=((cards *) malloc(individualhandsize*sizeof(cards)));//THIS IS WHERE IT ALL GOES WRONG!!
        printf("made it this far chaps!!\n");

        memcpy(individualhand,playerhand,individualhandsize*sizeof(cards));
        printf("made it this far chaps!!\n");

        printf("The cards available to player %d are ",i);
        /*i have yet to add code here*/

    }

    return nr_players;
}

void handcat(cards **playerhand,cards *playerx, int nr_cards){

    memcpy(*playerhand,playerx,nr_cards*sizeof(cards));

    return;
}


void playerflopcat(cards **playerhand,cards *playerx,int j, int nr_cards,int handsize){

    memcpy((*playerhand+(handsize+(2*j))),playerx,nr_cards*sizeof(cards));

    return;
}

我用来调用函数handget的方法:

int main(void) {
    int handsize=0, playerhandsize=0, nr_of_players=0;
    cards *thishand, *playerhands;

    handsize = flop(&thishand);
    //flop asks user for list of cards
    //user inputs(e.g. "d5 d6 d7 d8 d9")
    //flop returns int handsize=5

    printhand(thishand,handsize);
    //printhand returns a list (of handsize length) of the cards making up thishand
    //e.g. "d5 d6 d7 d8 d9"

    nr_of_players = handget(&playerhands,thishand,handsize);
    //handget is the function we're looking at
    //takes thishand which was assigned (using function flop) to a space in memory containing list of cards ("d5 d6 d7 d8 d9")
    //also uses int handsize = 5
    //playerhands is assigned in function handget

    //  printhand(playerhands,(handsize+(nr_of_players*2)));

    return 0;
}

为了完整起见,我已经包含了功能翻转

int flop(cards **handPtr) {
    int i,*q=NULL,n=NULL;
    int j[5]={0,0,0,0,0};
    int k[5]={1,1,1,1,1},nr_of_cards = 5;//for more/less cards CHANGE HERE!
    char rawsuit, rawcard[4];

    // allocate the required amount of memory for your cards
    (*handPtr) = (cards *) malloc(nr_of_cards * sizeof(cards));

    n=memcmp(j,k,sizeof(j));
    while(n!=0) {
        printf("Please input the five cards on the table: ");
        q=rawtoflop(*handPtr,nr_of_cards);
        for (i=0;i<nr_of_cards;i++) {
            j[i]=*(q+i);
        }
        n=memcmp(j,k,sizeof(j));
    }
    return nr_of_cards;
}

islegal的代码:

int islegal(cards *hand, int nr_of_cards) {
    int i, fulldeck[4][13]={0};
    int current_value, current_suit;
    cards *current_card = hand;
    int legal = 1; 

    for (i=0; i<nr_of_cards; i++) {
        current_value = (int) (*current_card).value;
        current_suit = (*current_card).suit;

        // if the current card has value zero, it is not a valid hand
        if (current_value==0) {
            legal = 0;
            break;
        }

        //check if the current card already appears, if yes invalid hand, if no, 
        //change the flag for that card in the full deck. 
        //Since (two) will correspond to fulldeck[.][0] there is a -2 offset.
        if ( (fulldeck[current_suit][current_value - 2]) > 0 ) {
            legal = 0;
            break;
        } else {
            fulldeck[current_suit][current_value - 2]++;
        }
        current_card++;
    }

    return legal;
}

1 个答案:

答案 0 :(得分:1)

您正在将函数handget称为:

nr_of_players = handget(&playerhands,thishand,handsize);

没关系,它会编译,因为handget确实期望cards **。但是,您从未为cards **分配空间。playerhands仍然是cards*并且获取其地址并尝试分配内存,这可能是malloc失败的原因。

您是否可以通过声明cards ** playerhands而不是当前的card *来尝试运行此功能?