我的纸牌游戏程序具有以下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
答案 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));
波恩胃口!