首页 > 解决方案 > 在struct中设置数组值时的非法操作

问题描述

对于纸牌游戏程序,我有以下 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

标签: c

解决方案


typedef struct _game {
    ...
} *Game;

Game被定义为一个别名struct _game *,一个指针。

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

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

正确的分配是:

Game game = malloc(sizeof *game);

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

如果可能的话,去掉!*的定义中的Game! 实在是太不合适了。


推荐阅读