newbie: array of structs?

D

decoy

Hi,
I'm having a little trouble with structs, can someone please help?

I have the following:

struct Card
{
Image* image;
int value;
};
struct Card* cards[52];

and assign it here:

int count = 0;
int a = 0;
int total = 0;
char* letter[] = {"c","d","h","s"};
char filename[10];

while(a < 13)
{
sprintf(filename, "%s%d.png", letter[count], a);
struct Card c;
c.image = loadImage(filename);
if(!c.image)
{
printf("failed to load: %s", filename);
}
c.value = a == 0 ? 0 : (a + 1 > 10 ? 10 : a+1);

cards[total++] = &c;

if(a == 12)
{
count++;
if(count ==4) a = 1000000;
else a =0;
}
else
{
a++;
}
}


My problem is that when I go through the array I only seem to get the
values for the last Card object that I added:

int b = 0;
while(b < 52)
{
struct Card* cg = cards;
printf("%d) value: %d\n", b++, (*cg).value);
blitAlphaImageToScreen(0 ,0 ,72 , 96, (*cg).image, 210,100);
}


Many thanks in advance for your help.
 
I

Ico

Hi,
I'm having a little trouble with structs, can someone please help?

I have the following:

struct Card
{
Image* image;
int value;
};
struct Card* cards[52];

and assign it here:

int count = 0;
int a = 0;
int total = 0;
char* letter[] = {"c","d","h","s"};
char filename[10];

while(a < 13)
{
sprintf(filename, "%s%d.png", letter[count], a);
struct Card c;
c.image = loadImage(filename);
if(!c.image)
{
printf("failed to load: %s", filename);
}
c.value = a == 0 ? 0 : (a + 1 > 10 ? 10 : a+1);

cards[total++] = &c;
[...]

My problem is that when I go through the array I only seem to get the
values for the last Card object that I added:

Here you assign the address of the automatic variable 'struct Card c'
to one of the pointers in your array. The problem is that automatic
variables are no longer valid as soon as you leave the scope where it
is defined.

Instead, you probably need to allocate memory for each of your card[]
pointers. Try something like :

struct Card *c;

c = malloc(sizeof *c);
if(c == NULL) ... /* Put your error handling code here */

c->image = loadImage(filename);

...

cards[total++] == c;

Ico
 
E

Eric Sosman

Hi,
I'm having a little trouble with structs, can someone please help?

I have the following:

struct Card
{
Image* image;
int value;
};
struct Card* cards[52];

and assign it here:

int count = 0;
int a = 0;
int total = 0;
char* letter[] = {"c","d","h","s"};
char filename[10];

while(a < 13)
{
sprintf(filename, "%s%d.png", letter[count], a);
struct Card c;
c.image = loadImage(filename);
if(!c.image)
{
printf("failed to load: %s", filename);
}
c.value = a == 0 ? 0 : (a + 1 > 10 ? 10 : a+1);

cards[total++] = &c;

if(a == 12)
{
count++;
if(count ==4) a = 1000000;
else a =0;
}
else
{
a++;
}
}


My problem is that when I go through the array I only seem to get the
values for the last Card object that I added:

There's only one `struct Card' object in the program,
the one named `c' inside the loop. You load `c' with the
data for a particular card, then aim one of the `cards[]'
pointers at it, then promptly overwrite `c' and aim the
next `cards[]' pointer at it, ... At the end, all the
`cards[]' pointers are aimed at the single `c', which
holds the last thing you put in it.

Actually, the situation is worse than that. `c' only
exists while the body of the loop is executing. A `c' is
created shortly after the loop begins, and ceases to exist
when you reach the closing }. Then you loop around for
another iteration, which creates a new `c' that lives only
until you get to the } again. So you actually wind up with
`card[]' holding pointers to something that has ceased to
exist by the time the loop is over ... What you probably
want to do is have `cards[]' be an array of `struct card',
not an array of `struct card*'. You can copy the entirety
of `c' into the right `cards[]' element, or you can get
rid of `c' altogether and just work directly with the
`cards[]' elements themselves.

By the way, your programs will become far easier to
read if you learn to use C's looping constructs a little
better. Look at all those hoops you're jumping through
to get `a' and `count' to cycle around in the way you want,
and contrast that complexity with the simplicity of

total = 0;
for (count = 0; count < 4; ++count) {
for (a = 0; a < 13; ++a) {
...
cards[total++] = c;
}
}

Well, I know which one *I'd* prefer to read ...
 
D

decoy

I understand what's going wrong now, thanks. I'm fairly new to C (from
Java and c#) so all of this pointer stuff can get a little confusing at
times, I suppose it just requires a bit more practise :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,173
Messages
2,570,937
Members
47,481
Latest member
ElviraDoug

Latest Threads

Top