在struct

时间:2018-10-10 01:55:54

标签: c

我的纸牌游戏程序具有以下3种结构

// Linked list of cards, used for draw & discard pile, players' hands
typedef struct cardStack {
    struct cardStack *next;
    Card *card;
} CardStack;

// A player and their hand
typedef struct player {
    int playerNumber;
    CardStack *hand;
} Player;

typedef struct _game {
    CardStack *discardPile;
    CardStack *drawPile;    
    Player *players[4];
    int currentPlayer;
    int currentTurn;
} *Game;

和此功能初始化游戏结构

Game newGame(int deckSize, value values[], color colors[], suit suits[]) {

    Game game = (Game)malloc(sizeof(Game));

    game->players[0] = (Player*)malloc(sizeof(Player));
    game->players[0] = &(Player){0, NULL};
    game->players[1] = (Player*)malloc(sizeof(Player));
    game->players[1] = &(Player){1, NULL};
    game->players[2] = (Player*)malloc(sizeof(Player));
    game->players[2] = &(Player){2, NULL};
    game->players[3] = (Player*)malloc(sizeof(Player));
    game->players[3] = &(Player){3, NULL};

    for (int i = 1; i <= 7; i++) {
        for (int j = 1; i <= NUM_PLAYERS; i++) {
            Card card = newCard(values[i * j - 1], colors[i * j - 1], suits[i * j - 1]);
            addToStack(card, game->players[j-1]->hand);
        }
    }

    CardStack *discardPile = (CardStack*)malloc(sizeof(CardStack));
    Card firstDiscard = newCard(values[28], colors[28], suits[28]);
    addToStack(firstDiscard, discardPile);
    game->discardPile = discardPile;

    CardStack *drawPile = (CardStack*)malloc(sizeof(CardStack));
    for (int i = 29; i < deckSize; i++) {
        Card card = newCard(values[i], colors[i], suits[i]);
        addToStack(card, drawPile);
    }
    game->drawPile = drawPile;

    game->currentPlayer = 0;
    game->currentTurn = 1;

    return game;
}

它可以正常编译,但是当我尝试运行它时,此行

game->players[0] = (Player*)malloc(sizeof(Player));

类似,给出错误 “非法数组,指针或其他操作” 我不确定是怎么回事,因为我只是将一个指针(在结构体的指针数组中)设置为另一个指针

编辑:不幸的是,这是给定头文件的任务,所以我别无选择,只能使用指针typedef

3 个答案:

答案 0 :(得分:3)

typedef struct _game {
    ...
} *Game;

{Game被定义为指针struct _game *的别名。

Game game = (Game)malloc(sizeof(Game));

这意味着sizeof(Game)是指针的大小,而不是整个结构的大小。指针小于整个结构,因此内存不足。写入->players会访问已分配区域之外的内存,这会导致非法操作错误。

正确的分配应该是:

Game game = malloc(sizeof *game);

经验教训:使用p = malloc(sizeof *p)而不是p = malloc(sizeof(Type))可以避免这种错误。编译器不会捕获大小不匹配的内容。即使sizeof *p更改了类型,p也将始终是正确的大小。

如果可能的话,请摆脱*的定义中的Game!太不合适了。

答案 1 :(得分:2)

除了memory allocation所标识的John Kugelman问题之外,您还有至少一个主要问题……

另一个问题

请注意以下两行:

game->players[0] = (Player*)malloc(sizeof(Player));
game->players[0] = &(Player){0, NULL};

小心泄漏分配的内存。您用刚好指向复合文字的指针替换了刚刚分配的指针,这使您无法释放分配的内存。只要不超出范围,修改复合文字是完全合法的,但是在函数返回时,它确实会超出范围,因此,如果您不但泄漏内存,还可以修改不再拥有的数据更改播放器信息。

您可能需要这样做,它将复合文字复制到分配的内存中:

game->players[0] = (Player*)malloc(sizeof(Player));
*game->players[0] = (Player){0, NULL};

如果发现还有其他问题,我不会感到惊讶,但是代码不是MCVE(Minimal, Complete, Verifiable Example),因此很难确定。

答案 2 :(得分:0)

不要在结构定义的末尾使用指针,这很丑。

将其更改为:

typedef struct _game {
   CardStack *discardPile;
   CardStack *drawPile;    
   Player *players[4];
   int currentPlayer;
   int currentTurn;
} Game;

然后在您的malloc中将该语句替换为以下内容:

Game* games = (Game*)malloc(sizeof(Game));

波恩胃口!