struct 字段中的随机值

vla*_*d27 1 c struct pointers

我正在尝试学习一些 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);
Run Code Online (Sandbox Code Playgroud)

我有一个printCard接受单个指针并打印值的函数,以及一个调用printCard52 次的打印平台函数。如果我在创建卡片时打印卡片,一切都会顺利,但如果我在卡片创建之后打印卡片,因为某些原因我会在第 6 张卡片上出现段错误。我启动gdb并注意到这个输出:

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);
Run Code Online (Sandbox Code Playgroud)

其余输出正常。在检查第 6 张卡的价值时,我得到:

Seven of Diamonds<br>
(null) of Diamonds<br>
Nine of Diamonds<br>
Run Code Online (Sandbox Code Playgroud)

如果我跳过第 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]);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

打印甲板代码:

前:

void printDeck(card* c){
    for(int i = 0; i < 52; i++){
        printCard(c);
        c += sizeof(card);
    }
}
Run Code Online (Sandbox Code Playgroud)

后:

void printDeck(card* c){
    for(int i = 0; i < 52; i++){
        printCard(c);
        c++;
    }
}
Run Code Online (Sandbox Code Playgroud)

打印卡没有改变:

void printCard(card* c){
    printf("%s of %s\n", face_str[c->face], suit_str[c->suit]);
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 6

您的代码中的问题是这一行:

Deck += sizeof(card);
Run Code Online (Sandbox Code Playgroud)

这里,Deck是一个card *(指向card)。如果你想前进一个位置,指针算法会为你完成这项工作,并且Deck + 1已经sizeof(card)提前了。指针的加法或减法p总是前进的sizeof(*p)

正确的代码是:

Deck += 1;
// or 
Deck++;
Run Code Online (Sandbox Code Playgroud)

循环后也犯了同样的错误,这里:

Deck -= sizeof(card) * 52;
Run Code Online (Sandbox Code Playgroud)

应该是:

Deck -= 52;
Run Code Online (Sandbox Code Playgroud)

我是 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);
Run Code Online (Sandbox Code Playgroud)


chm*_*ike 5

向我们展示该printDeck函数的代码会很有趣。

您在给定代码中遇到的问题是Deck += sizeof(card)。您认为这会sizeof(card)进一步移动 Deck字节。但这是不正确的。当 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);
Run Code Online (Sandbox Code Playgroud)

您可能在printDeck.