我的 C 数组在执行期间损坏

My C array gets corrupted during execution

我正在为纸牌游戏编写 C 程序,目前正在编写算法来向每位玩家发牌。问题是,似乎没有任何原因,我的数组指针之一在执行期间被设置为 0,我不知道为什么。它似乎发生在我代码中的一个非常特定的位置。这是我声明数组的地方:

struct Hand *hands = (struct Hand*)calloc(players, sizeof(struct Hand));
for (int player = 0; player < leftovers; player++) {
    //Allocate an extra spot for these players, since they take an
    //extra card
    hands[player].cardv = (struct Card*)calloc((cardsperplayer + 1), sizeof(struct Card));
    hands[player].cardc = cardsperplayer + 1;
}
for (int player = leftovers; player < players; player++) {
    //Allocate the normal amount of cards for the rest of the players
    hands[player].cardv = (struct Card*)calloc((cardsperplayer), sizeof(struct Card));
    hands[player].cardc = cardsperplayer;
}

接下来,我们跳过制作一副纸牌并为其填充纸牌值的部分,跳到我正在洗牌并准备发牌的部分。似乎洗牌一结束,指向 hands 数组的指针就坏了。

//Then we add the jokers on the end
struct Card blackJoker = {0, 13};
deck[52] = blackJoker;
struct Card redJoker = {1, 13};
deck[53] = redJoker;
//Now, we shuffle the deck using the Fisher Yates shuffle (the Durstenfeld version)
for (int cardsleft = 54; cardsleft > 0; cardsleft--) {
    swapCards(deck, cardsleft, rand() % cardsleft);
}
//IT SEEMS TO DROP THE HANDS ARRAY RIGHT HERE...run 
//Now that the cards are randomly shuffled, we just deal them out to
// everyone (it doesn't matter about the order, this is supposed to
//be truly random!
currentCard = 0;
for (int player = 0; player < leftovers; player++) {
    //Deal an extra card for these players, since they take an extra
    //card
    for (int card = 0; card < hands[player].cardc; card++) {
        hands[player].cardv[card] = deck[currentCard];
        currentCard++;
    }
}

我不明白的是,在访问 hands 数组之前或之后的任何时候都没有。但是,手数组最终还是死了,我因为试图访问一个疯狂的地址而得到了一个段错误。我也会包含代码的其他部分以供参考。

void swapCards(struct Card *set, int a, int b) {
struct Card temp = set[a];
set[a] = set[b];
set[b] = temp;

这是我用来存放卡片和手牌的结构:

struct Card {
int suit;
int value;
};

struct Hand {
    int cardc;
    struct Card* cardv;
};

如果您想 运行 完整的应用程序,它是托管在 Github 上的 C 程序,位于 https://github.com/Mikumiku747/kingandserf 除了 C 编译器和 make 之外,它不需要任何先决条件。至于一些最后的证明,我通过调试器把它放在一起,这就是我如何找到它出错的地方:

Reading symbols from /home/pi/kingandtheserf/bin/kats...done.
(gdb) b cardops.c:90
Breakpoint 1 at 0x8a58: file src/cardops.c, line 90.
(gdb) b cardops.c:94
Breakpoint 2 at 0x8aa8: file src/cardops.c, line 94.
(gdb) b cardops.c:98
Note: breakpoint 2 also set at pc 0x8aa8.
Breakpoint 3 at 0x8aa8: file src/cardops.c, line 98.
(gdb) run a a a
Starting program: /home/pi/kingandtheserf/bin/kats a a a

Breakpoint 1, dealHands (players=4, sort=0) at src/cardops.c:91
91      for (int cardsleft = 54; cardsleft > 0; cardsleft--) {
(gdb) p hands
 = (struct Hand *) 0x13008
(gdb) p hands[0]
 = {cardc = 14, cardv = 0x13030}
(gdb) p hands[2]
 = {cardc = 13, cardv = 0x13120}
(gdb) c
Continuing.

Breakpoint 2, dealHands (players=4, sort=0) at src/cardops.c:98
98      currentCard = 0;
(gdb) p hands
 = (struct Hand *) 0x2
(gdb) p hands[0]
Cannot access memory at address 0x2
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00008b30 in dealHands (players=4, sort=0) at src/cardops.c:102
102         for (int card = 0; card < hands[player].cardc; card++) {
(gdb) quit

即使有人不知道如何解决这个问题,他们至少可以告诉我发生了什么事吗?我以前从未见过这个,我现在唯一的猜测是优化器以某种方式破坏了它。

循环中对 swapCards 的第一次调用将索引 54 处的卡片与另一张交换,但 deck 数组中的最高索引是 53。