Unions in C
Unions are like structures but all members share the same memory. Useful for saving memory when you only need one field at a time.
What You Will Learn
- ✓Understand how unions share memory
- ✓Know when to use union vs struct
- ✓Calculate union size (largest member)
- ✓Use unions for variant types
01What is a Union?
A union is similar to a structure, but with one key difference: all members share the same memory location. This means a union can only hold one member's value at a time.
Structure vs Union Memory
Structure (Separate Memory)
Total: 12 bytes (with padding)
Union (Shared Memory)
int / float / char
All share same space
Total: 4 bytes (size of largest)
Key Difference
- • Structure: Each member has its OWN memory — can store all values
- • Union: All members SHARE memory — only ONE value at a time
02Declaring and Using Unions
1#include <stdio.h>23// Define a union4union Data {5 int i;6 float f;7 char c;8};910int main() {11 union Data data;12 13 // Store an integer14 data.i = 42;15 printf("data.i = %d\n", data.i);16 17 // Store a float (overwrites the integer!)18 data.f = 3.14;19 printf("data.f = %.2f\n", data.f);20 printf("data.i = %d (garbage now!)\n", data.i); // Corrupted!21 22 // Store a character (overwrites the float!)23 data.c = 'A';24 printf("data.c = %c\n", data.c);25 26 // Size of union = size of largest member27 printf("\nSize of union: %zu bytes\n", sizeof(data));28 printf("Size of int: %zu, float: %zu, char: %zu\n",29 sizeof(int), sizeof(float), sizeof(char));30 31 return 0;32}Output:
data.f = 3.14
data.i = 1078523331 (garbage now!)
data.c = A
Size of union: 4 bytes
Size of int: 4, float: 4, char: 1
🔍 How This Program Works
union Data data — Creates a union variable. Only 4 bytes allocated (size of largest member: int or float).
data.i = 42 — Stores 42 in those 4 bytes. Currently interpreted as an integer.
data.f = 3.14 — Overwrites the same 4 bytes with float representation of 3.14. Integer value is now garbage!
data.i now shows 1078523331 — the float's binary pattern interpreted as an integer (meaningless).
sizeof(data) returns 4 — always equals the largest member, not the sum of all members.
⚠️ Important!
When you write to one union member, it overwrites ALL other members. Only the last written member contains valid data!
03Union Memory Layout
All union members start at the same memory address. The union's size equals the size of its largest member.
union Data { int i; float f; char c; }
All members start at address 0x1000 — they overlap completely!
1#include <stdio.h>23union Data {4 int i;5 float f;6 char c;7};89int main() {10 union Data data;11 12 // All members have the SAME address!13 printf("Address of data: %p\n", (void*)&data);14 printf("Address of data.i: %p\n", (void*)&data.i);15 printf("Address of data.f: %p\n", (void*)&data.f);16 printf("Address of data.c: %p\n", (void*)&data.c);17 18 // All print the same address!19 20 return 0;21}Union Size Rule
sizeof(union) = size of largest member (plus padding if needed)
04Structure vs Union Comparison
| Feature | Structure | Union |
|---|---|---|
| Keyword | struct | union |
| Memory | Each member has own space | All members share space |
| Size | Sum of all members (+padding) | Size of largest member |
| Access | All members at once | Only one member at a time |
| Use Case | Group related data | Store one of many types |
1#include <stdio.h>23struct StructExample {4 int i; // 4 bytes5 float f; // 4 bytes6 char c; // 1 byte (+3 padding)7}; // Total: 12 bytes89union UnionExample {10 int i; // 4 bytes11 float f; // 4 bytes12 char c; // 1 byte13}; // Total: 4 bytes (largest member)1415int main() {16 printf("Size of struct: %zu bytes\n", sizeof(struct StructExample));17 printf("Size of union: %zu bytes\n", sizeof(union UnionExample));18 19 return 0;20}05Practical Use Cases
1. Variant Type (Store Different Types)
1#include <stdio.h>2#include <string.h>34// A variant that can hold int, float, or string5typedef struct {6 int type; // 0 = int, 1 = float, 2 = string7 union {8 int i;9 float f;10 char str[20];11 } value;12} Variant;1314void printVariant(Variant v) {15 switch (v.type) {16 case 0: printf("Integer: %d\n", v.value.i); break;17 case 1: printf("Float: %.2f\n", v.value.f); break;18 case 2: printf("String: %s\n", v.value.str); break;19 }20}2122int main() {23 Variant v1 = {0, .value.i = 42};24 Variant v2 = {1, .value.f = 3.14};25 Variant v3;26 v3.type = 2;27 strcpy(v3.value.str, "Hello");28 29 printVariant(v1);30 printVariant(v2);31 printVariant(v3);32 33 return 0;34}2. Memory-Efficient Data Structures
1#include <stdio.h>23// Network packet that can be different types4typedef struct {5 int packetType; // 1 = text, 2 = binary, 3 = command6 int length;7 union {8 char text[256];9 unsigned char binary[256];10 struct {11 int commandId;12 int params[4];13 } command;14 } payload;15} Packet;1617int main() {18 Packet p;19 p.packetType = 1;20 p.length = 5;21 22 // Only 256 bytes for payload, not 256+256+20!23 printf("Packet size: %zu bytes\n", sizeof(Packet));24 25 return 0;26}3. Type Punning (Access Different Representations)
1#include <stdio.h>23// View the same bytes as different types4union FloatBits {5 float f;6 unsigned int bits;7 unsigned char bytes[4];8};910int main() {11 union FloatBits fb;12 fb.f = 3.14f;13 14 printf("Float value: %f\n", fb.f);15 printf("As integer (bits): 0x%08X\n", fb.bits);16 printf("As bytes: ");17 for (int i = 0; i < 4; i++) {18 printf("%02X ", fb.bytes[i]);19 }20 printf("\n");21 22 return 0;23}06Common Mistakes
❌ Reading Wrong Member
union Data d;d.f = 3.14;printf("%d", d.i); // WRONG! You stored a float, not int // This prints garbage/meaningless valueAlways read the same member you last wrote to!
❌ Expecting All Values to Persist
union Data d;d.i = 42;d.f = 3.14;d.c = 'A';// WRONG assumption: all three values are stored// Only d.c is valid now - others are overwritten!❌ Forgetting to Track Active Member
// BAD: No way to know which member is validunion Data { int i; float f; };// GOOD: Use a struct with type indicatorstruct TaggedUnion { int type; // Track which member is active union { int i; float f; } value;};07Summary
What You Learned:
- ✓Union: All members share the same memory location
- ✓Size: Equals the size of the largest member
- ✓One at a time: Only one member holds valid data
- ✓Use cases: Variant types, memory efficiency, type punning
- ✓Best practice: Track which member is active with a type field
08Next Steps
Continue learning about other derived data types: