I have a struct defined like this:
typedef struct
{
int num;
char letter;
}* Foo;
And an array like this:
Foo* items = malloc(sizeof(Foo) * 4);
From my understanding and from the (accepted) answer to this question Dynamic array of pointers to structs, I would expect the above line to only reserve the memory for 4 Foo items, but doesn't initialize it - i.e., if I try to access items[i]->num
, I should get some kind of error.
Also, in order to insert item into this array, I should do this:
items[0] = malloc(sizeof(*items[0]));
However, I did a little test, and seems like the following code prints 1
and a
just fine:
Foo* items = malloc(sizeof(Foo) * 2);
items[0]->num = 4;
items[0]->letter = 'a';
printf("items[0] = {num=%d, char=%c}\n", items[0]->num, items[0]->letter);
I'm confused. Is this the expected behavior?
Your initial malloc:
Foo* items = malloc(sizeof(Foo) * 4);
Is creating an array of 4 pointers, since Foo
is a pointer type. So your second malloc:
items[0] = malloc(sizeof(*items[0]));
Makes sense, since you're allocating a struct to that pointer.
However, the assignment you're doing leads to undefined behavior because you didn't do the second malloc
and therefore no space has been allocated to items[0]
yet. C won't prevent you from writing to a memory location you shouldn't be writing to. And once you do that, anything can happen.
One thing that's a bit confusing here is that you used typedef
to define a pointer type. That can lead to a lot of confusion since it's not apparent by looking at the type that it's a pointer. And in this case, because of how you defined Foo
, you had an extra layer of pointer indirection you probably don't need.
So if you define your struct like this:
typedef struct
{
int num;
char letter;
} Foo;
Then this can be done safely:
Foo* items = malloc(sizeof(Foo) * 2);
items[0].num = 4;
items[0].letter = 'a';
printf("items[0] = {num=%d, char=%c}\n", items[0].num, items[0].letter);
Now the malloc creates an array of structs instead of an array of pointers to structs, so an additional layer of mallocs is no longer necessary.