Memory Alignment & Padding
int stored at an address that is a multiple of 4 can be fetched in a single memory access. Misaligned data — say, a 4-byte int starting at address 3 — may require the CPU to perform two separate reads and stitch the result together, or on some architectures may not be allowed at all and trigger a hardware fault. To avoid this, the C compiler carefully places every variable and struct member at an address that respects its type's alignment requirement.Struct Padding
sizeof(struct) can be larger — sometimes much larger — than the simple sum of its members' sizes.#include <stdio.h>
struct example {
char a; // 1 byte
int b; // 4 bytes, needs 4-byte alignment
char c; // 1 byte
};
int main(void) {
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof(int) = %zu\n", sizeof(int));
printf("naive sum = %zu\n", sizeof(char) + sizeof(int) + sizeof(char));
printf("sizeof(struct example) = %zu\n", sizeof(struct example));
return 0;
}sizeof(char) = 1 sizeof(int) = 4 naive sum = 6 sizeof(struct example) = 12
On a typical 64-bit platform this struct is 12 bytes, not 6. The layout in memory looks like this:
offset 0: a (1 byte)
offset 1: [padding] (3 bytes, so 'b' can start on a 4-byte boundary)
offset 4: b (4 bytes)
offset 8: c (1 byte)
offset 9: [padding] (3 bytes, so the struct's total size is a multiple
of its largest member's alignment -- 4 here)Reordering Members to Reduce Padding
Because padding is driven purely by member order and alignment, you can often shrink a struct simply by reordering its fields — largest members first, smallest last — with no change in behavior:
// Before: 12 bytes due to padding around the single char members
struct bad_layout {
char a;
int b;
char c;
};
// After: 8 bytes -- both chars pack into the same 4-byte slot
struct good_layout {
int b;
char a;
char c;
};short, then char). This is a purely mechanical change that can noticeably shrink memory usage for large arrays of structs, with zero cost to readability._Alignof and _Alignas (C11)
_Alignof(type) reports a type's required alignment in bytes, and _Alignas(n) forces a variable or struct member to be aligned to a specific boundary — useful for things like SIMD data or matching a hardware-mandated layout.#include <stdalign.h>
#include <stdio.h>
int main(void) {
printf("alignof(int) = %zu\n", _Alignof(int));
printf("alignof(double) = %zu\n", _Alignof(double));
_Alignas(16) char buffer[64]; // force 16-byte alignment
printf("buffer address is 16-byte aligned: %d\n",
((size_t)buffer % 16) == 0);
return 0;
}sizeof(struct).CPUs read aligned memory more efficiently, and some architectures fault on misaligned access entirely
The compiler inserts invisible padding bytes between struct members to keep each one properly aligned
sizeof(struct)can be larger than the sum of its members due to this paddingOrdering struct members from largest to smallest often reduces or eliminates unnecessary padding
_Alignofand_Alignas(C11) let you query and control alignment explicitly