c - 使用 malloc 进行指针分配出错

标签 c pointers malloc

请随意复制粘贴并尝试一下,当单独的手在内存中分配了空间时,它会在函数handget中途停止工作

/* 
 * A program that is meant to classify five-card poker hands. 
 *Is still in progress
 */

#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

#define SEED 7
#define SIZE 5

/*
 *
 */

typedef enum suits {
   clubs,
   diamonds,
   hearts,
   spades
} suits;

typedef enum values {
    zero,
    one, // not used, but ensures numerical values correspond
    two,
    three,
    four,
    five,
    six,
    seven,
    eight,
    nine,
    ten,
    jack,
    queen,
    king,
    ace
} values; 

typedef struct cards {
    suits suit;
    values value;
} cards;

int islegal(cards *hand, int nr_of_cards);
/* Given any number of cards, determines whether any duplicates
 * or false cards are present or not. If so, returns 0, otherwise 1. 
 */
int flop(cards **handPtr); 
/* Asks the user to input a hand of cards; 
 * returns the number of cards being input
 */
int *rawtoflop (cards *handPtr, int nr_of_cards);

int hander(cards **handPtr,int counter); 

int handget(cards **playerhands,cards *thishands, int handsize);

void printsuit(suits thissuit);
/* Prints the enum-type suits
 */

void printvalue(values thisvalue);
/* Prints the enum-type values
 */

void printhand(cards *hand, int nr_of_cards); 
/* Prints a hand of cards without further processing 
*/
int main(void) {
    cards *thishand, *playerhands;

    flop(&thishand);
    printhand(thishand,6);
    handget(&playerhands,thishand,6);

    return 0;
}

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

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

    free(&handPtr);
    return nr_of_cards;
}

int *rawtoflop (cards *handPtr, int nr_of_cards){
    int i,m[5],*mPtr;
    char rawsuit, rawcard[4];

    mPtr=m;
        // 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;
        }

        m[i]=(islegal(handPtr,i+1));
    }
    return mPtr;
}


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=NULL,*individualhand=NULL;
    int nr_players=1;

    (*playerhand) = (cards *) malloc(7*sizeof(cards));

    memcpy(*playerhand,thishands,handsize*sizeof(cards));

    printf("Please enter the cards for player 1: ");

    hander(&player,0);
    memcpy(*playerhand+5,player,7*sizeof(cards));

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

    return nr_players;
}

void printsuit(suits thissuit) {
    switch (thissuit) {
        case diamonds:
            printf("d");
            break;
        case clubs:
            printf("c");
            break;
        case hearts:
            printf("h");
            break;
        case spades:
            printf("s");
            break;
        }
    return;
}

void printvalue(values thisvalue) {
    switch (thisvalue) {
        case two:
            printf("2");    
            break;
        case three:
            printf("3");
            break;
        case four:
            printf("4");
            break;
        case five:
            printf("5");
            break;
        case six:
            printf("6");
            break;
        case seven:
            printf("7");
            break;
        case eight:
            printf("8");
            break;
        case nine:
            printf("9");
            break;
        case ten:
            printf("10");
            break;
        case jack:
            printf("J");
            break;
        case queen:
            printf("Q");
            break;
        case king:
            printf("K");
            break;
        case ace:
            printf("A");
            break;
    }

    return;
}


void printhand(cards *hand, int nr_of_cards) {
    int i;

    for (i=0; i<nr_of_cards; i++) {
        printsuit((hand[i]).suit);
        printvalue((hand[i]).value);
        printf(" ");
    }
    printf("\n");

    return;
}

最佳答案

您为 7 张卡分配了足够的空间:

(*playerhand) = (cards *) malloc(7*sizeof(cards));

然后将七张牌复制到*playerhand+5中:

memcpy(*playerhand+5,player,7*sizeof(cards));

所以你会遇到缓冲区溢出。 *playerhand+5&(*playerhand)[5] 相同。因此,您要将 7 张卡复制到一个数组中的第五个位置,该数组的容量足以容纳 7 张卡。

这是使用魔数(Magic Number)的一个问题。如果你不给它起个名字,我就猜不出这个“5”是什么意思(也不知道为什么是 7 张牌)。

关于c - 使用 malloc 进行指针分配出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8408218/

相关文章:

c++ - 通过引用传递参数时,可以将 & 号 "&"放在哪里?

c - C中的内存泄漏,结构中的二维数组

c - 在返回函数之前释放分配的内存

c - 如何在 linux 平台上的 qt 中将控制台输出重定向到 GUI

c - c中链表的选择排序

c++ - 未排序链表段错误去除重复元素

c++将指针从构造函数传递给构造函数

c - 数组的地址与数组[0]的地址 - C语言

c - 输入/输出lzw问题

c - ((void(*)(void))0)() 是 Exit 函数吗?