[英]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.