I ran into this problem debugging an AVR microcontroller: I have a main.c file with numerous variable definitions, amongst them an array of structs, like this:
struct mystruct mystruct_array[COUNT];
In another .c file I refer to this array as external, but I left away the array brackets and size so I wouldn't repeat myself and just declared the variable as a pointer (because arrays are essentially pointers, aren't they?):
extern struct mystruct *mystruct_array;
But when I checked the address of the array using printf("%p\n", mystruct_array);
I got a null pointer instead of the array's location in memory. Also if I would access the subsequent items in the array, like printf("%p\n", &(mystruct_array[n]));
it would print address 0 plus n
times sizeof(struct mystruct)
.
Only after I changed the definition to
extern struct mystruct mystruct_array[COUNT];
(exactly the same as in main.c), I got the true address of the array.
My question: Why does this make a difference to the compiler (in my case avr-gcc)?
That's a fun one.
When you write :
struct mystruct mystruct_array[COUNT];
You create a global array of mystruct
structs, there are COUNT
of them, and since you didn't initialize it, it'll be filled with zeros.
When you then write:
extern struct mystruct *mystruct_array;
You tell the compiler that there's a variable called mystruct_array
somewhere and that it's a pointer. But it's not, it's an array. So the compiler is going to read the content of the array as if it were a pointer.
So when you try to output the value of that pointer, the compiler goes fetch mystruct_array
in memory and outputs its content as if it were a pointer. Since it's actually an array full of zeros, you're seeing a null pointer in the output.
Instead you should write something like:
extern struct mystruct mystruct_array[];
So the compiler knows the correct type of your variable. You can specify the length in the square brackets here, but you don't have to.
I'd recommend you go read up on the differences between pointers and arrays to make sure you don't confuse them in the future.