📦

C Struct Memory Alignment Visualizer

Visualize memory offsets, compiler padding waste, and data boundaries for 32-bit architecture.

C Struct Definition
32-bit Memory Grid Representation
Data
Padding (Waste)
Memory Offset Breakdown Table
Offset (Byte) Type Member Name Size (Bytes)
💡 Struct Alignment & Optimization Guide

In 32-bit embedded systems (like ARM Cortex-M), the compiler aligns member variables to their natural boundaries. This can introduce invisible padding bytes (waste) if members are declared in an inefficient order.

Alignment Rules:

  • char / uint8_t: 1-byte alignment
  • short / uint16_t: 2-byte alignment
  • int / float / pointer: 4-byte alignment
  • double / int64_t / uint64_t: 8-byte alignment (ARM EABI)

How to Optimize:

Sort your struct members by size in descending order (largest types first). This minimizes padding waste to 0%.

Try This Example (Copy & Paste to Visualizer):

❌ Unoptimized (12 bytes)
uint8_t status;
uint32_t timestamp;
uint8_t mode;
✅ Optimized (8 bytes)
uint32_t timestamp;
uint8_t status;
uint8_t mode;
💡 Usage & Formula

C Struct Alignment represents how compilers lay out variables in memory. 32-bit MCUs (like ARM Cortex-M) align variables to their natural boundaries, inserting padding bytes (waste) if declarations are unoptimized.

Alignment Rules:

  • char / uint8_t: 1-byte alignment
  • short / uint16_t: 2-byte alignment
  • int / float / pointer: 4-byte alignment
  • double / int64_t / uint64_t: 8-byte alignment (ARM EABI)
  • union: Starts at offset 0, aligned to maximum member alignment
  • bit-field: Packed into base type containers

Optimization: Sort your structure members by size in descending order (largest first) to minimize compiler-introduced padding to 0%.

When you need it: Laying out a C struct for a packet, register block or shared memory, and wondering why sizeof is bigger than the sum of the members — or chasing a hard fault from an unaligned access.

Worked example: struct { char a; int b; char c; } on a 4-byte-align target lays out as a@0, pad@1-3, b@4, c@8, pad@9-11 → sizeof = 12, not 6. Reorder to { int b; char a; char c; } and it packs to sizeof = 8.

Tips & gotchas:

  • Order members largest-to-smallest to minimise padding without any packing pragma.
  • #pragma pack (or __attribute__((packed))) gives a wire-exact layout, but reading a misaligned member can fault or run slowly on Cortex-M0 and other strict-align cores.
  • Natural alignment usually equals the type's own size; a struct's alignment is that of its widest member.
  • Don't take the address of a packed member and dereference it as an aligned pointer — copy the bytes instead.