Skip to main content

Memory & Language Features

Structures & Unions

Complete lesson for Structures & Unions using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with C++ OOP and STL where relevant.

L1

Basics — Structures & Unions

Section: Memory & Language Features. C++ structures and unions — memory layout, struct vs class, and C union vs C++ union.

What is a structure (struct)?

  • A **structure** groups related variables (possibly of different types) under **one name**.
  • Each member has its **own** memory (unlike a union).
  • Access members with the **dot** operator: s.name, or p->name via pointer.
  • **Real-life:** a student record — roll, name, marks together; an employee — id, salary, department.
  • **Real-life:** a product — id, title, price, stock.
IdeaMeaningExample
struct typeBlueprint for a recordstruct Student { ... };
Object / variableOne concrete recordStudent s;
MemberField inside the structs.marks
Dot / arrowAccess members.roll / ptr->roll
#include <iostream>
#include <string>
using namespace std;

struct Student {
    int roll;
    string name;
    float marks;
};

int main() {
    Student s = {101, "Asha", 92.5f};
    cout << s.roll << " " << s.name << " " << s.marks << "\n";
    return 0;
}

Why we need structures

  • Without structs you juggle many parallel arrays (rolls[i], names[i], marks[i]) — easy to mismatch.
  • A struct keeps one entity’s data together and passes cleanly to functions.
  • Foundation for classes/OOP — in C++ a struct can also have methods.
Without structWith structBenefit
Many separate variablesOne Student sGrouped data
Parallel arraysStudent a[50]One index = one person
Hard function APIsvoid print(const Student&)Clear parameter
Error-prone updatesUpdate members togetherLess mismatch

Structure memory allocation

  • Members are stored **one after another** (with possible **padding** for alignment).
  • sizeof(Struct) is at least the sum of member sizes — often larger due to padding.
  • Each struct object gets its own copy of all members.
  • **Real-life analogy:** a form with separate boxes for name, age, city — each box takes its own space on the page.
Example membersTypical sizes (illustrative)Notes
char a;1 byteMay be followed by padding
int b;4 bytes (common)Often aligned to 4
double c;8 bytes (common)Often aligned to 8
Whole structsizeof(S)≥ sum; padding possible
#include <iostream>
using namespace std;

struct Demo {
    char a;   // 1
    int b;    // 4
    char c;   // 1
};

int main() {
    Demo d{};
    cout << "sizeof(Demo) = " << sizeof(Demo) << "\n";
    cout << "sizeof(d.a) = " << sizeof(d.a) << "\n";
    cout << "sizeof(d.b) = " << sizeof(d.b) << "\n";
    // sizeof(Demo) is often > 1+4+1 because of padding
    return 0;
}

Arrays of structures & nested structures

  • Student classList[40]; — one array, many student records.
  • A struct can contain another struct: Address inside Employee.
  • **Real-life:** company employee with nested home address fields.
#include <iostream>
#include <string>
using namespace std;

struct Address {
    string city;
    int pin;
};

struct Employee {
    int id;
    string name;
    Address addr;
};

int main() {
    Employee e{1, "Ravi", {"Hyderabad", 500001}};
    cout << e.name << " - " << e.addr.city << "\n";
    return 0;
}

What is a union?

  • A **union** is like a struct, but all members **share the same memory**.
  • Size of a union ≈ size of its **largest** member (plus possible padding).
  • Only one member’s value is meaningful at a time (you must remember which is active).
  • **Real-life analogy:** one shared locker used either for a laptop bag or a helmet — not both at full size at once; space is the larger item.
  • **Real-life:** a packet that holds either an int id or a float sensor value, never needing both fully at once.
#include <iostream>
using namespace std;

union Data {
    int i;
    float f;
    char c;
};

int main() {
    Data d{};
    d.i = 42;
    cout << "as int: " << d.i << "\n";
    d.f = 3.14f; // overwrites same storage
    cout << "as float: " << d.f << "\n";
    cout << "sizeof(Data) = " << sizeof(Data) << "\n";
    return 0;
}

Union memory allocation

  • All members start at the **same address** (overlay).
  • Writing one member and reading another (wrong active member) is a classic bug / undefined in many cases — treat carefully.
  • Use unions when you truly need storage saving or type-punning patterns (advanced/low-level); prefer safer designs in app code.
Pointstructunion
Member storageSeparate (side by side)Shared (overlay)
Typical sizeSum of members (+ padding)Size of largest member (+ pad)
Active valuesAll members valid togetherOne member at a time
Accesss.a and s.b both OKRemember which member you set
AnalogyForm with many filled fieldsOne shared locker

Differences between C union and C++ union

  • Both share storage among members, but **C++ unions** have extra rules because C++ has constructors, destructors, and non-trivial types.
  • In modern C++, prefer **std::variant** for type-safe “one of several types” instead of raw unions with complex types.
PointC unionC++ union
Basic ideaMembers share memorySame — members share memory
Typical membersMostly POD / scalar typesSame, but more rules for complex types
Methods inside unionNot in classic CCan have member functions (limited cases)
Constructors / destructorsN/A (C)Allowed; non-trivial members need care
Non-trivial types (string, etc.)Not typical / restrictedAllowed only with special handling; easy to misuse
Access controlNo public/privateCan use access specifiers
Anonymous unionCommon extension / C11Supported — members appear in enclosing scope
Type safetyManual — you track active memberStill manual for raw union; std::variant is safer
InheritanceNoCannot be a base; limited OOP use
Preferred modern useLow-level C code, embeddedLow-level / tagged unions; else std::variant
Exampleunion U { int i; float f; };Same syntax works; plus C++ features carefully

struct vs class in C++

  • In C++, struct and class are almost the same.
  • Default member access: **public for struct**, **private for class**.
  • Default inheritance: public for struct, private for class.
  • Convention: struct for plain data aggregates; class for encapsulated objects with invariants.
Pointstructclass
Default accesspublicprivate
Can have methods?YesYes
Can have ctors?YesYes
Typical styleData bundle / POD-ishEncapsulated type
OOP usable?YesYes
struct Point {
    int x, y; // public by default
    int sum() const { return x + y; }
};

class Account {
    int balance; // private by default
public:
    void deposit(int x) { balance += x; }
};

Passing structures to functions

  • Prefer const Struct& to read without copying; Struct& to modify.
  • Passing by value copies all members — fine for tiny structs, costly for large ones.
#include <iostream>
#include <string>
using namespace std;

struct Book {
    string title;
    float price;
};

void printBook(const Book& b) {
    cout << b.title << " - " << b.price << "\n";
}

void discount(Book& b, float pct) {
    b.price *= (1.0f - pct / 100.0f);
}

int main() {
    Book b{"C++ Guide", 499.0f};
    discount(b, 10);
    printBook(b);
    return 0;
}

When to use struct vs union

  • Choose based on whether fields must coexist.
NeedUseExample
Several fields valid togetherstructStudent roll+name+marks
One field active to save memoryunion (or variant)Payload as int OR float
Type-safe “one of many”std::variantModern C++ alternative to union
OOP with invariantsclassBank account rules
L2

Advanced — Structures & Unions

Padding, alignment, and sizeof

  • Compilers insert padding so members sit on preferred alignment boundaries.
  • Reorder members (largest alignment first, or pack related fields) to sometimes shrink sizeof.
  • Never assume a fixed layout across compilers/ABIs without checking — important for binary file formats and networking.
  • #pragma pack / attributes can change packing — use sparingly and portably.

Tagged unions (safe union pattern)

  • Pair a union with an enum tag that records which member is active.
  • This is the classic “discriminated union” pattern — std::variant automates it.
#include <iostream>
using namespace std;

enum class Kind { Int, Float };

struct Tagged {
    Kind k;
    union {
        int i;
        float f;
    };
};

int main() {
    Tagged t{Kind::Int, {}};
    t.i = 10;
    if (t.k == Kind::Int) cout << t.i << "\n";
    return 0;
}

std::variant — modern alternative

  • std::variant holds one of several types safely.
  • Use std::get, std::holds_alternative, or std::visit.
  • Prefer variant over raw union when types have constructors/destructors.
#include <iostream>
#include <variant>
#include <string>
using namespace std;

int main() {
    variant<int, float, string> v = 42;
    cout << get<int>(v) << "\n";
    v = string("hello");
    cout << get<string>(v) << "\n";
    return 0;
}

Anonymous unions and bit-fields (overview)

  • Anonymous union members are accessed as if declared in the enclosing struct.
  • Bit-fields pack bits into integers — useful for flags; layout is implementation-defined.
  • Common in hardware registers and protocol headers (advanced/systems code).

Real-life models

  • Hospital: struct Patient with id, name, vitals.
  • E-commerce: struct Order nesting Address and line items.
  • Game: struct Vec3 { float x,y,z; } for positions.
  • Network packet header as struct; optional payload overlay as union/variant.
  • Settings value that is either int, bool, or string → variant better than raw union.
L3

Tricky Interview Points

Q1) What is a structure in C++?

Answer A user-defined type that groups related variables (members) under one name. Each member has its own storage (with possible padding).

Q2) What is a union?

Answer A user-defined type whose members share the same memory. Size is typically that of the largest member. Only one member should be considered active at a time.

Q3) Difference between struct and union?

Answer Struct members have separate memory and can all be used together. Union members overlay the same memory to save space; only one is active at a time.

Q4) How is memory allocated for a structure?

Answer Members are laid out sequentially with possible padding for alignment. sizeof(struct) is at least the sum of member sizes and may be larger.

Q5) How is memory allocated for a union?

Answer All members share one overlapping storage region sized for the largest member (plus possible padding).

Q6) Differences between C union and C++ union?

Answer Both share storage. C++ unions can have methods/access control and interact with constructors/destructors; non-trivial members need careful handling. Modern C++ often prefers std::variant for type-safe alternatives.

Q7) struct vs class in C++?

Answer They are nearly identical. Default access and default inheritance are public for struct and private for class.

Q8) What is padding in structures?

Answer Extra bytes inserted by the compiler so members meet alignment requirements. It can increase sizeof.

Q9) Can a structure contain another structure?

Answer Yes — nested structures are common (e.g. Employee containing Address).

Q10) How do you pass a struct to a function efficiently?

Answer Pass by const reference to read, or by reference to modify — avoids copying all members.

Q11) What is a tagged union?

Answer A union plus an enum (or similar) that records which member is currently active, improving safety.

Q12) What is std::variant?

Answer A type-safe union in the C++ standard library that can hold one of several alternative types and tracks which is active.

L4

Simple Programs

Student structure demo

#include <iostream>
#include <string>
using namespace std;

struct Student {
    int roll;
    string name;
    float marks;
};

int main() {
    Student s{10, "Neha", 88.0f};
    cout << s.roll << " " << s.name << " " << s.marks << "\n";
    return 0;
}

sizeof struct vs union

#include <iostream>
using namespace std;

struct S { int a; float b; char c; };
union U { int a; float b; char c; };

int main() {
    cout << "sizeof(S) = " << sizeof(S) << "\n";
    cout << "sizeof(U) = " << sizeof(U) << "\n";
    return 0;
}

Union overlay demo

#include <iostream>
using namespace std;

union Number {
    int i;
    float f;
};

int main() {
    Number n{};
    n.i = 10;
    cout << n.i << "\n";
    n.f = 2.5f;
    cout << n.f << "\n";
    cout << "sizeof = " << sizeof(n) << "\n";
    return 0;
}

Array of structures

#include <iostream>
#include <string>
using namespace std;

struct Item {
    string name;
    int qty;
};

int main() {
    Item cart[3] = {{"Pen", 2}, {"Book", 1}, {"Bag", 3}};
    for (const Item& it : cart)
        cout << it.name << " x" << it.qty << "\n";
    return 0;
}

Nested structure — Employee

#include <iostream>
#include <string>
using namespace std;

struct Address { string city; int pin; };
struct Employee { int id; string name; Address addr; };

int main() {
    Employee e{7, "Kiran", {"Pune", 411001}};
    cout << e.name << ", " << e.addr.city << "-" << e.addr.pin << "\n";
    return 0;
}

Tagged union pattern

#include <iostream>
using namespace std;

enum class Type { Int, Float };
struct Value {
    Type t;
    union { int i; float f; };
};

int main() {
    Value v{Type::Float, {}};
    v.f = 9.81f;
    if (v.t == Type::Float) cout << v.f << "\n";
    return 0;
}

std::variant alternative

#include <iostream>
#include <variant>
using namespace std;

int main() {
    variant<int, double> v = 3.14;
    if (holds_alternative<double>(v))
        cout << get<double>(v) << "\n";
    return 0;
}
L5

Problem Solving Tricks

  • struct = many fields together; union = shared storage, one active field.
  • Print sizeof to see padding effects — do not guess layouts blindly.
  • Pass large structs by const reference.
  • Default: public in struct, private in class.
  • C++ union ≠ free pass for string/vector members — prefer std::variant.
  • Use a tag enum with unions for safety.
  • Nested structs model real forms (Address inside Employee).
  • Initialize aggregates with braces: Student{1, "A", 90}.
  • Arrow -> when you have a pointer to a struct.
  • For “one of several types” in modern C++, reach for variant first.
  • Compare sizeof(struct) vs sizeof(union) in a tiny demo to remember the difference.
  • Document which union member is active if you must use raw unions.
L6

Practice Programs List

  1. Create struct Book with title, author, price; print three books in an array.
  2. Write sizeof for a struct with char, int, double and explain padding.
  3. Build Employee with nested Address; read/print city and pin.
  4. Create a union with int and float; show sizeof and overwriting behavior.
  5. Make a table (on paper) of C union vs C++ union differences from the lesson.
  6. Implement a tagged union holding either int marks or float gpa.
  7. Pass struct Player by const reference to print and by reference to addScore.
  8. Compare struct vs class default access with a tiny example.
  9. Rewrite a tagged union using std::variant.
  10. Design struct Order with id, customer name, and total; compute bill for an array.
  11. Show that changing union.f corrupts reading union.i if tag is ignored.
  12. Create struct Date and struct Event containing Date.
  13. Measure sizeof before/after reordering members in a padded struct.
  14. List five real-life records that should be structs, and two that might use union/variant.