Skip to content
UniCircle
MediumConceptualStructures and unions

struct vs union, and why sizeof(struct) is bigger than you expect

Question C-STR-005

What is the difference between a struct and a union? Given struct S { char c; int i; char d; };, why is sizeof(struct S) usually 12 and not 6?

Show the explanation

struct: every member has its own storage, laid out in the order you declare them. The size is at least the sum of the members' sizes.

union: all members share the same storage, starting at the same address. The size is the size of the largest member, rounded up for alignment. Only one member holds a meaningful value at a time. Uses: saving memory in variant records (usually with a "tag" field that says which member is active), and looking at the same bytes in different ways in low-level code.

C
union Value { int i; float f; char bytes[4]; };   /* sizeof == 4 on common platforms */

Padding and alignment. CPUs read data fastest, and on some architectures only, when an object sits at an address that is a multiple of its alignment. A 4-byte int usually needs a multiple of 4. The compiler therefore inserts unused padding bytes:

struct S { char c; int i; char d; };
offset 0: c   | 1-3: padding | 4-7: i | 8: d | 9-11: padding  -> sizeof == 12

The padding at the end makes the size a multiple of the struct's alignment, so every element of an array of S is also aligned.

Reordering helps: struct T { int i; char c; char d; }; takes 8 bytes (4 + 1 + 1 + 2 bytes of padding). A good rule is to declare members from largest to smallest.

Notes

  • Exact sizes depend on the platform and compiler. Say "usually" in the interview.
  • #pragma pack or __attribute__((packed)) removes padding. It is used for file formats and network headers, but access can be slower and is not portable.
  • Use offsetof(struct S, i) from <stddef.h> to see where each member starts.
  • Never compare structs with memcmp, because padding bytes can hold garbage.

Original UniCircle question. Last reviewed 22 Oct 2026.