I'm trying to learn some C and I've started with a simple deck of cards program.
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.
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. 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. I fired up gdb
and noticed this output:
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:
(gdb) p c->face
$10 = 2675
If i am skipping the 6th card the output is fine and everything works the way it should. I'm new to C but i can't really see how that value got put in that field in my code.
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
). If you want to advance of one position, pointer arithmetic does the job for you, and doing Deck + 1
already advances sizeof(card)
ahead. Adding or subtracting from a pointer p
always advances 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.
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
). This is undefined behavior in C, and therefore trying to print such a value could result in random values being printed (if not worse).
I would suggest you to completely avoid modifying the value of Deck
, and instead index it like an array:
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.
The problem you have in the given code is Deck += sizeof(card)
. You assumed that this would move Deck sizeof(card)
bytes further. But that is not correct. When Deck is a pointer on card
, incrementing Deck by one will increment its address by sizeof(card)
bytes.
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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.