Embedded C

Alignment & Padding

C's Structs & Unions mentioned, as a gotcha, that a struct's size is often larger than the sum of its fields. This chapter is why: CPUs read memory fastest — sometimes exclusively — at specific address boundaries, and the compiler inserts invisible filler bytes to guarantee every field lands on one, whether you asked for it or not.

Quick reference
What it is
The rule that a type's address must be a multiple of its own alignment requirement, and the compiler-inserted padding bytes that make that true inside a struct.
Mental model
Parking spaces painted only every 4 meters — a car (a 4-byte int) can only park on a painted line, even if that leaves an empty gap behind the car in front of it.
Key numbers
A type's alignment requirement commonly equals its own size (a 4-byte int wants a 4-byte-aligned address); a struct's overall alignment is the strictest of any of its members.
Reach for it when
Minimizing a struct's memory footprint on a RAM-constrained target, or explaining an unexpectedly large sizeof(struct ...).

Why alignment exists

Many CPUs read memory in fixed-size chunks (words) starting only at addresses that are multiples of that chunk size. Reading a 4-byte int that happens to start at an address that isn't a multiple of 4 either costs extra CPU cycles (the processor fetches two words and stitches the value together) or, on some architectures, isn't allowed at all and faults immediately. The compiler avoids both outcomes by never placing a field at a misaligned address in the first place.

Padding, in a worked example

struct Example {
    char  a;   // 1 byte
    int   b;   // 4 bytes — needs a 4-byte-aligned address
    char  c;   // 1 byte
};

printf("%zu\n", sizeof(struct Example));   // 12, not 1 + 4 + 1 = 6
struct Example lays out as a (1 byte), 3 padding bytes, b (4 bytes), c (1 byte), then 3 more padding bytes, totaling 12 bytes struct Example — 12 bytes total, not 6 a 3 bytes padding (aligns b to 4 bytes) b c padding The trailing padding exists so an ARRAY of Example keeps every element's own "b" field aligned too
Two separate padding regions, both invisible in the struct definition itself — one to align b, one so a second element in an array would also start aligned.

Reordering fields to save space

The compiler is not allowed to reorder your struct's fields — but you can, and doing so can meaningfully shrink a struct by grouping same-size (or naturally-aligned) fields together:

struct Wasteful {
    char  a;   // 1 byte + 3 padding
    int   b;   // 4 bytes
    char  c;   // 1 byte + 3 padding
};   // sizeof = 12

struct Tight {
    int   b;   // 4 bytes
    char  a;   // 1 byte
    char  c;   // 1 byte + 2 padding (to keep the struct itself 4-byte aligned)
};   // sizeof = 8 — same fields, smaller struct

A simple, reliable rule of thumb: declare a struct's fields from largest to smallest.

Checking a struct's real size

Never guess a struct's size — measure it, and on a target where every byte of RAM matters, treat an unexpectedly large sizeof result as worth investigating:

printf("Wasteful: %zu bytes\n", sizeof(struct Wasteful));   // 12
printf("Tight:    %zu bytes\n", sizeof(struct Tight));       // 8

Real-world applications

Gotchas

Field notes