Prev: CVAPI(void)
Next: solutions manuals
From: inquisitive on 24 Oct 2008 12:27 Can someone please help me to understand why the following trivial program would segfault? #include <stdio.h> #include <stdlib.h> #include <string.h> enum{ black, red }; enum{ Hearts, Diamonds }; enum{ Clubs, Spades }; typedef struct Card { int color; int suit; int value; }Card; typedef Card Deck[52]; void LoadDeck(Deck * myDeck) { int i = 0; for(; i < 51; i++) { myDeck[i]->color = i % 2; myDeck[i]->suit = i % 4; myDeck[i]->value = i % 13; } } void PrintDeck(Deck * myDeck) { int i = 0; for(;i < 52; i++) { printf("Card %d %d %d\n",myDeck[i]->color, myDeck[i]->suit, myDeck[i]->value); } } int main() { Deck myDeck; memset(&myDeck,0,sizeof(Deck)); LoadDeck(&myDeck); PrintDeck(&myDeck); return 0; } It appears to segfault on this line. myDeck[i]->color = i % 2; But only when i equals 2. Any ideas on what I've done wrong here? By the way I'm just trying to create a standard 52 card deck.
From: Ike Naar on 24 Oct 2008 13:36 In article <ab5ba7b0-aaed-4d20-84ca-873ca06b23db(a)b31g2000prb.googlegroups.com>, <inquisitive(a)mailinator.com> wrote: >Can someone please help me to understand why the following trivial >program would segfault? > /* [snip] */ > >typedef struct Card >{ > int color; > int suit; > int value; >}Card; > >typedef Card Deck[52]; > >void LoadDeck(Deck * myDeck) >{ > > int i = 0; > for(; i < 51; i++) > { > myDeck[i]->color = i % 2; (*myDeck)[i].color = i % 2; /* see below */ > myDeck[i]->suit = i % 4; > myDeck[i]->value = i % 13; > } >} In LoadDeck, myDeck is a pointer to Deck; *myDeck is a Deck, i.e. an array of Card. (*myDeck)[i] is the i-th Card in that array; and (*myDeck)[i].color is the color member of that Card. Ike
From: Ben Bacarisse on 24 Oct 2008 13:44 inquisitive(a)mailinator.com writes: > Can someone please help me to understand why the following trivial > program would segfault? Basically, you have one too many levels of pointer. > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > > enum{ > black, > red > }; > > enum{ > Hearts, > Diamonds > }; > > enum{ > Clubs, > Spades > }; This is not right since (in C) both Clubs and Hearts are the same value (0). > typedef struct Card > { > int color; > int suit; > int value; > }Card; Again, a little odd to separate the colour from the suit, but that is not really a problem. > typedef Card Deck[52]; > > void LoadDeck(Deck * myDeck) But this is. You want to pass a pointer to Card, not a Deck. Alternatively, if you really do want to pass a Deck * (there is no point, but it is legal to do so) you must access the cards within that deck like this: (*myDeck)[i].value = i % 13; and so on. But really I'd use: void LoadDeck(Card *myDeck) and inside the access becomes: myDeck[i].value = i % 13; You can use your typedef, but that obscures the fact that the parameter is a pointer to the first element of an array: void LoadDeck(Deck myDeck) /* note no *. Obscure and not advised. */ > { > > int i = 0; > for(; i < 51; i++) I think you mean 52 here. > { > myDeck[i]->color = i % 2; > myDeck[i]->suit = i % 4; > myDeck[i]->value = i % 13; > } > } > > void PrintDeck(Deck * myDeck) > { > int i = 0; > for(;i < 52; i++) > { > printf("Card %d %d %d\n",myDeck[i]->color, myDeck[i]->suit, > myDeck[i]->value); > } > } > > int main() In C it is better to write: int main(void) > { > Deck myDeck; > memset(&myDeck,0,sizeof(Deck)); > LoadDeck(&myDeck); > PrintDeck(&myDeck); What you write here depends on how you solve the problems above, but if you go with the simplest option, all the & can be removed. > return 0; > } -- Ben.
From: Bart van Ingen Schenau on 24 Oct 2008 14:11 inquisitive(a)mailinator.com wrote: > Can someone please help me to understand why the following trivial > program would segfault? > > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > > enum{ > black, > red > }; > > enum{ > Hearts, > Diamonds > }; > > enum{ > Clubs, > Spades > }; > > > typedef struct Card > { > int color; > int suit; > int value; > }Card; > > typedef Card Deck[52]; > > void LoadDeck(Deck * myDeck) Here you declare myDeck as a pointer to an array of 52 Card objects. > { > > int i = 0; > for(; i < 51; i++) > { > myDeck[i]->color = i % 2; > myDeck[i]->suit = i % 4; > myDeck[i]->value = i % 13; This looks like you try to access 52 arrays of a single Card pointer each. This should be: (*myDeck)[i].color = i % 2; (*myDeck)[i].suit = i % 4; (*myDeck)[i].value = i % 13; and similar in PrintDeck. <snip> > It appears to segfault on this line. > myDeck[i]->color = i % 2; > But only when i equals 2. That is just coincidence. It could just as easily have segfaulted with any other value of i > 0. > > Any ideas on what I've done wrong here? Due to the 'typedef Card Deck[52]', you got your use of array indexing wrong. That is one of the big pitfalls when using a typedef for an array type. Bart v Ingen Schenau -- a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq c.l.c FAQ: http://c-faq.com/ c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
From: Fabiano on 27 Oct 2008 08:12
inquisitive(a)mailinator.com ha scritto: > int main() > { > Deck myDeck; > memset(&myDeck,0,sizeof(Deck)); > LoadDeck(&myDeck); > PrintDeck(&myDeck); > return 0; > } I suppose... myDeck is an array, "myDeck" is a pointer yet to the array. try > memset(myDeck,0,sizeof(Deck)); > LoadDeck(myDeck); > PrintDeck(myDeck); Am I right? |