Data structure alignment is the way data is arranged and accessed in memory. This involves padding and packing to function properly.
Core Issue
CPUs most efficiently perform reads and writes when the data is aligned, meaning the address of the data is a multiple of the data size. To enable this improvement in speed, compilers will add padding to structs with variable data sizes.
Padding Rules
The compiler will look at the struct, and if the current member of the struct is positioned at a relative offset that is a multiple of its data size, it will place it there. If not, it will add padding until it is. It will then round up the total size of the struct to a multiple of the largest member.
Examples
struct X {
int a;
long b;
char c;
}In struct X, a is aligned as it is at the beginning of the struct. The member b, a long of 8 bytes is attempting to be slotted into the relative memory of X + 4, which is not a multiple of eight. Therefore, it pads by 4 bytes before placing itself into struct X. B’s offset is therefore 8 bytes compared to the start of X, and has 4 bytes of padding in between a and itself. C is aligned, a char would always be aligned as any place in memory is a multiple of one. The struct is currently 17 bytes in size, (4 from a, 4 from padding, 8 from long, 1 from c).
However, X’s total size needs to be a multiple of its largest member. Its largest member is b, a long which is 8 bytes in size. It therefore pads an additional 7 bytes of memory to be a total size of 24 bytes of memory.
Note that if the struct were constructed in the following way:
struct X {
long a;
int b;
char c;
}There would be no padding necessary int between a and b, therefore reducing the size of X to 16 bytes.
Keep in mind that these alignment rules are valid in nested structs as well. For example:
struct Y {
int a;
char b;
struct X;
}A is aligned since it’s at the beginning of the struct. B is aligned since its size is one byte. Struct X is attempting to place itself at offset 5, but its alignment requirement (as seen above) is eight. It will therefore add 3 bytes of padding after char b to align itself with struct Y. The alignment requirement of Y is now 8 bytes as well. Since X is 24 bytes total, there will be 4 (from a) + 1 (from b) + 3 (padding) + 24 (struct Y) 32 bytes. 32 is a multiple of eight, therefore we do not need to add any padding at the end of struct Y. The total size of struct Y is 32 bytes.