[英]Random value in struct field
我正在尝试学习一些 C 语言,并且我已经从一个简单的纸牌程序开始。
该卡是包含两个整数的结构体,用于面和花色。 我正在通过分配 52 张卡片并进行循环来构建一副套牌。
card *Deck = (card*)malloc(sizeof(card) * 52);
for(int i = 0; i < 4; i++){
for(int j = 1; j < 14; j++){
Deck->face = j;
Deck->suit = i;
Deck += sizeof(card);
}
}
Deck -= sizeof(card) * 52;
printDeck(Deck);
free(Deck);
我有一个接受单个指针并打印值的printCard
函数,以及一个调用printCard
52 次的打印组函数。 如果我在创建卡片时打印卡片,一切都会顺利,但是如果我在卡片创建之后因为某种原因打印卡片,我会在第 6 张卡片上出现段错误。 我启动了gdb
并注意到了这个输出:
Seven of Diamonds<br>
(null) of Diamonds<br>
Nine of Diamonds<br>
其余输出正常。 在检查第 6 张卡的价值时,我得到:
(gdb) p c->face
$10 = 2675
如果我跳过第 6 张卡,输出很好,并且一切正常。 我是 C 的新手,但我真的看不到该值是如何在我的代码中放入该字段的。
struct card{
int face;
int suit;
};
void printCard(card* c){
printf("%s of %s\n", face_str[c->face], suit_str[c->suit]);
}
编辑:
打印甲板代码:
前:
void printDeck(card* c){
for(int i = 0; i < 52; i++){
printCard(c);
c += sizeof(card);
}
}
后:
void printDeck(card* c){
for(int i = 0; i < 52; i++){
printCard(c);
c++;
}
}
打印卡没有改变:
void printCard(card* c){
printf("%s of %s\n", face_str[c->face], suit_str[c->suit]);
}
您的代码中的问题是这一行:
Deck += sizeof(card);
这里, Deck
是一张card *
(指向card
指针)。 如果你想前进一个位置,指针算术会为你完成这项工作,而做Deck + 1
已经提前了sizeof(card)
。 从指针p
添加或减去总是会增加sizeof(*p)
。
正确的代码是:
Deck += 1;
// or
Deck++;
循环后犯了同样的错误,这里:
Deck -= sizeof(card) * 52;
应该是:
Deck -= 52;
我是 C 的新手,但我真的看不到该值是如何在我的代码中放入该字段的。
当您错误地修改变量Deck
,您最终会访问超出分配块大小(即sizeof(card) * 52
)的内存。 这是 C 中未定义的行为,因此尝试打印这样的值可能会导致打印随机值(如果不是更糟的话)。
我建议你完全避免修改Deck
的值,而是像数组一样索引它:
card *Deck = malloc(sizeof(card) * 52);
for(int i = 0; i < 4; i++){
for(int j = 1; j < 14; j++){
Deck[i*13 + j]->face = j;
Deck[i*13 + j]->suit = i;
}
}
printDeck(Deck);
free(Deck);
向我们展示printDeck
函数的代码会很有趣。
您在给定代码中遇到的问题是Deck += sizeof(card)
。 您假设这会进一步移动 Deck sizeof(card)
字节。 但这是不正确的。 当 Deck 是card
上的一个指针时,将 Deck 增加 1 会将其地址增加sizeof(card)
个字节。
所以你的代码应该是
card *Deck = malloc(sizeof(card) * 52);
for(int i = 0; i < 4; i++){
for(int j = 1; j < 14; j++){
Deck->face = j;
Deck->suit = i;
Deck++;
}
}
Deck -= 52;
printDeck(Deck);
free(Deck);
您可能在printDeck
犯了同样的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.