Lesson 23
Structures and Unions
Covers structure and union syntax, memory layout, initialization, nested structures, and differences between structures and unions.
Lesson content
What are Structures and Unions?
A structure (struct) is a user-defined data type that groups variables of different data types into a single unit. Each member has its own separate memory location.
A union is also a user-defined data type, but all its members share the same memory location. At any given time, only one member can hold a valid value.
- A structure is like a house with multiple rooms. Each room stores different items independently.
- A union is like a single room that can be rearranged for different purposes. Only one arrangement is useful at a time.
Why do they exist?
- Keeping related information together
- Improving code readability
- Reducing memory usage (using unions)
- Modeling real-world entities
Real-world use cases
- Structures: student records, employee information, product details, bank accounts, game objects
- Unions: memory optimization, embedded systems, hardware programming, communication protocols, interpreting the same memory in different ways
Prerequisites
- Variables
- Data types
- Functions
- Arrays
- Pointers (basic understanding)
- Classes (optional but helpful)
Structure syntax
struct Student
{
int id;
string name;
float marks;
};
Student s1;
s1.id = 101;
s1.name = "Alice";
s1.marks = 92.5f;Each member has its own storage.
Union syntax
union Data
{
int number;
float decimal;
char letter;
};
Data d;All members share the same memory block.
Structure memory
struct Example
{
int x;
char y;
double z;
};
// Each member occupies separate memory.
// Padding may be added for alignment.Union memory
union Example
{
int x;
float y;
char z;
};
// Size equals the largest member.Structure vs union
- Memory allocation: separate for each member (structure) vs shared by all members (union)
- All members usable together: yes for structure, no for union
- Memory efficient: less for structure, more for union
- Data safety: better for structure, overwriting possible for union
- Typical use: general programming for structure, memory optimization for union
Initializing structures
Student s =
{
1,
"John",
95.0f
};Initializing unions
Data d;
d.number = 100;
// Later:
d.decimal = 3.14f;
// The previous value of number is overwritten
// because both members share the same memory.Example 1: Structure
#include <iostream>
#include <string>
using namespace std;
struct Student
{
int id;
string name;
float marks;
};
int main()
{
Student s;
s.id = 101;
s.name = "Alice";
s.marks = 94.5f;
cout << s.id << endl;
cout << s.name << endl;
cout << s.marks << endl;
return 0;
}Example 2: Array of structures
#include <iostream>
#include <string>
using namespace std;
struct Student
{
string name;
int age;
};
int main()
{
Student students[2];
students[0].name = "Tom";
students[0].age = 20;
students[1].name = "Emma";
students[1].age = 22;
for (int i = 0; i < 2; i++)
{
cout << students[i].name << " ";
cout << students[i].age << endl;
}
return 0;
}Example 3: Union
#include <iostream>
using namespace std;
union Data
{
int number;
float decimal;
};
int main()
{
Data d;
d.number = 100;
cout << d.number << endl;
d.decimal = 5.5f;
cout << d.decimal << endl;
return 0;
}Example 4: Nested structures
#include <iostream>
#include <string>
using namespace std;
struct Address
{
string city;
string country;
};
struct Employee
{
string name;
Address address;
};
int main()
{
Employee emp;
emp.name = "David";
emp.address.city = "London";
emp.address.country = "UK";
cout << emp.name << endl;
cout << emp.address.city << endl;
cout << emp.address.country << endl;
return 0;
}Example 5: Checking structure and union sizes
#include <iostream>
using namespace std;
struct StructExample
{
int number;
char letter;
double value;
};
union UnionExample
{
int number;
char letter;
double value;
};
int main()
{
cout << sizeof(StructExample) << endl;
cout << sizeof(UnionExample) << endl;
return 0;
}Common mistakes and pitfalls
- Accessing an uninitialized structure member. Fix: initialize members before use
- Assuming all union members keep their values. Fix: remember writing to one member overwrites the previous value
- Ignoring structure padding when estimating memory. Fix: use sizeof() to determine the actual size
- Forgetting the . operator to access members. Fix: use object.member or pointer->member
- Reading a different union member than the one most recently written. Fix: only read the member that was last assigned
Best practices
- Use structures for grouping related data
- Prefer classes when data hiding and member functions are required
- Use unions only when memory savings or low-level data representation is necessary
- Initialize structure members to avoid undefined values
- Use sizeof() rather than guessing object sizes
- Consider std::variant (C++17 and later) instead of raw unions for type-safe alternatives
When not to use this
- You need encapsulation, inheritance, or polymorphism (use classes)
- Multiple union members must hold valid values simultaneously
- Type safety is important and a modern alternative like std::variant is available
- The grouped data requires complex behavior in addition to storage
Summary
- Structures group related variables, with each member having its own memory
- Unions group members that share the same memory location
- Structures are ideal for representing real-world entities
- Unions are useful for reducing memory usage in specialized scenarios
- Structure size is typically the sum of its members plus possible padding
- Union size equals the size of its largest member
- Access structure members using the . operator (or -> for pointers)
- Writing to one union member replaces the previous active value
Frequently asked questions
What is the main difference between a structure and a union?
A structure allocates separate memory for every member, allowing all members to store values simultaneously. A union shares one memory block among all members, so only one member's value is considered valid at a time.
Why would I use a union instead of a structure?
Use a union when memory usage is critical and only one of several possible values needs to be stored at any given time, such as in embedded systems or communication protocols.
Can a structure contain another structure?
Yes. This is called a nested structure, and it's commonly used to model complex real-world objects.
How do I find the size of a structure or union?
Use the sizeof operator, such as sizeof(Student) or sizeof(Data). The result includes any padding added by the compiler for alignment.
Should I use struct or class in modern C++?
Use a struct when you're primarily storing data and public access is appropriate. Use a class when you need encapsulation, private data, and member functions. The main language difference is the default access level: members of a struct are public by default, while members of a class are private by default.