Sizeof union larger than expected. how does type alignment work here?

#include <stdio.h> union u1 { struct { int *i; } s1; struct { int i, j; } s2; }; union u2 { struct { int *i, j; } s1; struct { int i, j; } s2; }; int main(void) { printf(" size of int: %zu\n", sizeof(int)); printf("size of int pointer: %zu\n", sizeof(int *)); printf(" size of union u1: %zu\n", sizeof(union u1)); printf(" size of union u2: %zu\n", sizeof(union u2)); return 0; } 

Results in:

 $ gcc -O -Wall -Wextra -pedantic -std=c99 -o test test.c $ ./test size of int: 4 size of int pointer: 8 size of union u1: 8 size of union u2: 16 

Why does adding an integer of 4 bytes to the nested structure s1 of the union u2 increase the size of the whole by 8 bytes?

+3
source share
3 answers

The structure of u2.s2 is 16 bytes due to alignment restrictions. The compiler ensures that if you create an array of such structures, each pointer will be aligned on an 8-byte boundary. The *i field takes 8 bytes, then j takes 4 bytes, and the compiler inserts 4 bytes of padding. Because the structure has 16 bytes, the union containing it is also 16 bytes.

+7
source

This is because the compiler must support the entire structure (as well as the union) aligned to 8 bytes, because there is a pointer inside. (which in your case is 8 bytes)

Thus, even if you add only 4 bytes with an extra int , aligning the structure causes everything to be aligned to 8 bytes - hence +8, to bring the total size to 16 bytes.

The result is the following:

 struct { int *i, j; } s1; 

has a size of 16 bytes. Since the union must be no less than the largest element, it is also forced to 16.

http://en.wikipedia.org/wiki/Data_structure_alignment

+3
source

Since the pointer on your platform takes 8 bytes, it is likely that alignment of 8 bytes is also required. Therefore, when adding 4 more bytes, the structure cannot be 12 bytes in size, and in this case, individual elements, for example, the u2 array, will not be correctly aligned with the boundaries of 8 bytes, which is necessary for the pointer element. Therefore, you need to increase its size to the next multiple of 8, which is 16. The additional 4 bytes are simply not used / undefined.

+2
source

All Articles