简体   繁体   English

struct 字段中的随机值

[英]Random value in struct field

I'm trying to learn some C and I've started with a simple deck of cards program.我正在尝试学习一些 C 语言,并且我已经从一个简单的纸牌程序开始。

The card is struct containing two ints for face and suit.该卡是包含两个整数的结构体,用于面和花色。 And I'm building a deck by allocating 52 cards, and going thorough a loop.我正在通过分配 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);

I have a printCard function that takes a single pointer and prints the values, and a print deck function that calls printCard 52 times.我有一个接受单个指针并打印值的printCard函数,以及一个调用printCard 52 次的打印组函数。 If i print the cards as they are being created, everything goes well, but if i print the cards after all have been created for some reason I get a segfault at the 6th card.如果我在创建卡片时打印卡片,一切都会顺利,但是如果我在卡片创建之后因为某种原因打印卡片,我会在第 6 张卡片上出现段错误。 I fired up gdb and noticed this output:我启动了gdb并注意到了这个输出:

Seven of Diamonds<br>
(null) of Diamonds<br>
Nine of Diamonds<br>

The rest of the output is normal.其余输出正常。 When checking for the value of the 6th card i got:在检查第 6 张卡的价值时,我得到:

(gdb) p c->face
$10 = 2675

If i am skipping the 6th card the output is fine and everything works the way it should.如果我跳过第 6 张卡,输出很好,并且一切正常。 I'm new to C but i can't really see how that value got put in that field in my code.我是 C 的新手,但我真的看不到该值是如何在我的代码中放入该字段的。

struct card{
    int face;
    int suit;
};

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

Edit:编辑:

The printDeck code:打印甲板代码:

Before:前:

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

After:后:

void printDeck(card* c){
    for(int i = 0; i < 52; i++){
        printCard(c);
        c++;
    }
}

printCard didn't changed:打印卡没有改变:

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

The problem in your code is this line:您的代码中的问题是这一行:

Deck += sizeof(card);

Here, Deck is a card * (pointer to card ).这里, Deck是一张card * (指向card指针)。 If you want to advance of one position, pointer arithmetic does the job for you, and doing Deck + 1 already advances sizeof(card) ahead.如果你想前进一个位置,指针算术会为你完成这项工作,而做Deck + 1已经提前了sizeof(card) Adding or subtracting from a pointer p always advances sizeof(*p) .从指针p添加或减去总是会增加sizeof(*p)

The correct code would be:正确的代码是:

Deck += 1;
// or 
Deck++;

The same mistake is done after the loop, here:循环后犯了同样的错误,这里:

Deck -= sizeof(card) * 52;

Which should be:应该是:

Deck -= 52;

I'm new to C but i can't really see how that value got put in that field in my code.我是 C 的新手,但我真的看不到该值是如何在我的代码中放入该字段的。

When you wrongly modify the variable Deck , you end up accessing memory that is beyond the size of the allocated chunk (which is sizeof(card) * 52 ).当您错误地修改变量Deck ,您最终会访问超出分配块大小(即sizeof(card) * 52 )的内存。 This is undefined behavior in C, and therefore trying to print such a value could result in random values being printed (if not worse).这是 C 中未定义的行为,因此尝试打印这样的值可能会导致打印随机值(如果不是更糟的话)。


I would suggest you to completely avoid modifying the value of Deck , and instead index it like an array:我建议你完全避免修改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);

It would be interesting to show us the code of the printDeck function.向我们展示printDeck函数的代码会很有趣。

The problem you have in the given code is Deck += sizeof(card) .您在给定代码中遇到的问题是Deck += sizeof(card) You assumed that this would move Deck sizeof(card) bytes further.您假设这会进一步移动 Deck sizeof(card)字节。 But that is not correct.但这是不正确的。 When Deck is a pointer on card , incrementing Deck by one will increment its address by sizeof(card) bytes.当 Deck 是card上的一个指针时,将 Deck 增加 1 会将其地址增加sizeof(card)个字节。

So your code should be所以你的代码应该是

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);

You might have made the same error in printDeck .您可能在printDeck犯了同样的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM