I'm playing around with pointers and I've noticed one weird thing.
I have a struct as follow:
typedef struct list_element_struct {
uint32_t x;
uint32_t y;
uint32_t z;
struct list_element_struct *next;
}list_element;
As far as I know, the size of unsigned int is 4 bytes, and the size of a pointer is 8 bytes. Also there are 8 bytes aligned happened here so the size of this struct is 24 bytes.
I've initialized a list of above struct objects with list_element els[5];
and also set every piece of data in there to 0 with memset(els,0,5*sizeof(list_element));
Right now I'm trying to see their memory locations with these piece of code:
printf("%p start location of els\n", &(els));
printf("%p start location of els->x\n", &(els->x));
printf("%p start location of els->y\n", &(els->y));
printf("%p start location of els->z\n", &(els->z));
printf("%p start location of els->next(pointer)\n", &(els->next));
printf("%p start location of els+1\n", &(els[1]));
What I have as printed out is:
0x7ffeeba4a970 start location of els
0x7ffeeba4a970 start location of els->x
0x7ffeeba4a974 start location of els->y
0x7ffeeba4a978 start location of els->z
0x7ffeeba4a980 start location of els->next(pointer)
0x7ffeeba4a988 start location of els+1
Here is the weird thing. Why does els->z only takes two bytes? it really should take 4 like x and y.
Those numbers are hexadecimal. The difference between 0x7ffeeba4a978
and 0x7ffeeba4a980
is not 2 but 8.
To forestall your next question, the reason it's 8 and not 4 is likely due to alignment requirement. Many 64-bit systems either require or prefer to align their 8-byte pointers to 8-byte boundaries, i.e. to addresses which are a multiple of 8 (so that their least-significant hex digit is either 8
or 0
). So the compiler leaves 4 bytes of padding between z
and next
to achieve this.