Hi,
I am trying to understand how to manage arrays of pointers to structs. I built up some (verbose) simple code to build a struct containing an array of pointers to other structs. The main purpose is to really understand the increasingly complex syntax the more structs, pointers and arrays of pointers there are...
On line 41 I declare Item_Array my_array. And on line 60 I am looping through my_array (if pitem is not NULL) testing if the value in that array index is equal to NULL.
Why/How/When are the pointers in the my_array.items array initialised to NULL ? The declaration on line 41 means this struct is in automatic storage? Does that simply mean the reference (implying that my_array really contains a ptr under the hood) to the real struct? And that the real struct itself, because it is declared in static storage, initialises the pointers to NULL ?
My code:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXTEXT 15
#define MAXITEMS 10
typedef struct {
int i;
char text[MAXTEXT];
} Item; /* our new type is called Item */
typedef struct {
Item *items[MAXITEMS];
} Item_Array;
/* pointer to show uninitialised state in static storage */
Item *myitem;
int main(int argc, char **argv) {
/* pointer to show uninitialised state in automatic storage */
Item *myitem2;
printf("uninitialised: myitem %p (static storage) is nil\n", myitem);
printf("uninitialised: myitem2 %p (automatic storage) is garbage.\n", myitem2);
/* create some items */
Item item1, item2, item3;
item1.i = 1;
strncpy(item1.text, "one", MAXTEXT);
item2.i = 2;
strncpy(item2.text, "two", MAXTEXT);
item3.i = 3;
strncpy(item3.text, "three", MAXTEXT);
/* create a struct with an array of pointers to our items */
Item_Array my_array;
/* array of pointers should contain the addresses of item structs &item_struct */
my_array.items[0] = &item1;
my_array.items[1] = &item2;
my_array.items[2] = &item3;
/* create an item on the heap */
Item *fifth_item = malloc(sizeof(Item));
(*fifth_item).i = 5; /* pointer to struct (*pitem), then struct member .i */
strncpy((*fifth_item).text, "five on heap", MAXTEXT);
my_array.items[4] = fifth_item; /* pointer is already the address of the item */
int i;
for (i = 0; i < MAXITEMS; i++) {
Item *pitem; /* will hold a reference to the array item, to make things below more readable */
pitem = my_array.items[i]; /* array index contains pointer (address) to item struct */
if (pitem != NULL) {
/* dereference pointer to struct (*pitem), then access member with struct notation of .i */
printf("[%d] %d, %s, address %p\n", i, (*pitem).i, (*pitem).text, pitem);
}
else {
printf("[%d] uninitialised, is %p\n", i, pitem);
}
}
/* remember, remember, the fifth of November */
free(fifth_item);
return 0;
}
The output when run:
Code:
# ./pointers
uninitialised: myitem (nil) (static storage) is nil
uninitialised: myitem2 0x7ffe930ac3e0 (automatic storage) is garbage.
[0] 1, one, address 0x7ffe930ac2c0
[1] 2, two, address 0x7ffe930ac2a0
[2] 3, three, address 0x7ffe930ac280
[3] uninitialised, is (nil)
[4] 5, five on heap, address 0xb02010
[5] uninitialised, is (nil)
[6] uninitialised, is (nil)
[7] uninitialised, is (nil)
[8] uninitialised, is (nil)
[9] uninitialised, is (nil)