Structure vs Union
Structure and union: the core idea
Both struct and union let you group different data types under one name. They even look almost identical in code. The one difference that changes everything is how they use memory:
- A structure gives each member its own separate memory. All members exist together.
- A union puts all members in the same memory. Only one member is valid at a time.
Once you understand this, every other difference — size, behaviour, and use case — follows naturally.
How a structure stores memory
In a structure, member a sits in one place, member b sits in another. They never overlap.
#include <stdio.h>
struct Data {
int a; // its own 4 bytes
char b; // its own 1 byte
};
int main() {
struct Data d;
d.a = 65;
d.b = 'X';
printf("a = %d, b = %c\n", d.a, d.b); // both survive
printf("size = %lu bytes\n", sizeof(d));
return 0;
}a = 65, b = X
size = 8 bytes
Both a and b keep their values at the same time, because each has its own memory. (The size is 8, not 5, due to padding the compiler adds for alignment.)
How a union stores memory
Now the same members inside a union. They share one memory space, so writing one overwrites the other.
#include <stdio.h>
union Data {
int a; // shares the same memory
char b; // shares the same memory
};
int main() {
union Data d;
d.a = 65;
printf("a = %d\n", d.a);
d.b = 'X'; // overwrites a's memory
printf("b = %c\n", d.b);
printf("a is now = %d\n", d.a); // a is corrupted
printf("size = %lu bytes\n", sizeof(d));
return 0;
}a = 65
b = X
a is now = 88
size = 4 bytes
See how a changed to 88 after we set b = 'X'? That is because 'X' is ASCII 88, written into the very same bytes. In a union, the last member you write is the only one that is valid.
Why sizeof gives different results
This is a favourite interview question. The structure needed 8 bytes (4 for int + 1 for char + 3 padding). The union needed only 4 bytes — just enough for its largest member (the int). The char reuses part of that same space.
Structure size ≈ sum of all members (plus padding). Union size = size of the largest member.
A real-world use of union
Unions shine when a value can be one of several types, but only one at a time. Imagine a setting that is either a number or a letter grade — never both:
#include <stdio.h>
struct Result {
int isLetter; // a small "tag"
union {
int marks; // when isLetter == 0
char grade; // when isLetter == 1
} value;
};
int main() {
struct Result r;
r.isLetter = 0;
r.value.marks = 92;
if (r.isLetter) printf("Grade: %c\n", r.value.grade);
else printf("Marks: %d\n", r.value.marks);
return 0;
}Marks: 92
The little isLetter tag remembers which member is currently valid — a common, safe pattern called a "tagged union."
Structure vs union: full comparison
| Point | Structure | Union |
|---|---|---|
| Memory | Separate for each member | Shared by all members |
| Members active | All at once | Only one at a time |
| Size | Sum of members (+ padding) | Largest member |
| Writing one member | Others are unaffected | Others get overwritten |
| Keyword | struct | union |
| Best for | Records with many fields | One-of-several-types values |
When to use which
- Use a structure when you need to keep several pieces of data together at the same time — like a student's name, roll number and marks.
- Use a union when a value is one of several types but never more than one at once, and you want to save memory.
Common mistakes
- Reading a union member you did not write last — you get garbage or a reinterpretation, not the old value.
- Expecting all union members to hold data together like a structure.
- Forgetting that structure size includes padding, so it is often larger than the raw sum.
- Using a union to "save memory" when you actually need all fields — this corrupts data.
Create a union with an int, a float and a char. Print sizeof and confirm it equals the size of the largest member. Then write each member in turn and observe how the previous one changes.
Summary
- Structure = separate memory per member; all members usable together.
- Union = shared memory; only the last-written member is valid.
- Structure size = sum of members (+ padding); union size = largest member.
- Use a structure for records; use a union for one-of-several-types values that save memory.