我正在为一款纸牌游戏编写一个C程序,而且我正在制定算法来为每个玩家发牌。问题是,似乎没有理由,我的数组指针在执行过程中被设置为0,我无法弄清楚原因。它似乎发生在我的代码中的一个非常特定的地方。这里就是我声明数组:我的C数组在执行期间被破坏
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;
}
接下来,我们跳过,我做出一副扑克牌,并与卡值填充它,到了那里,我洗牌在甲板上的点的部分,准备好处理它们。似乎只要洗牌结束,指向手阵列的指针就会变差。
//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++;
}
}
我没有得到的东西是,直接在之前或之后的手阵列访问。但仍然,手阵列结束了死亡,我得到一个Segfault试图访问一个疯狂的地址。我将包含代码的其他部分,以供参考。
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
$1 = (struct Hand *) 0x13008
(gdb) p hands[0]
$2 = {cardc = 14, cardv = 0x13030}
(gdb) p hands[2]
$3 = {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
$4 = (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
即使有人不知道如何解决这个问题,可能他们至少告诉我发生了什么事。我以前从未见过这种情况,现在我唯一的猜测是优化器以某种方式破坏了它。
请张贴所有的变量声明。看哪,我可以看到未来:这将成为一个错综复杂的数组索引错误。 – Lundin
好的,我添加了hands数组的声明。感谢您查看它。如果您需要其他任何东西,我只会发布完整的标题和代码,其中大约80%已经存在。 – Mikumiku747