StudyLover
  • Home
  • Study Zone
  • Profiles
  • Typing Tutor
  • Contact us
  • Sign in
StudyLover Unions
Download
  1. C Programming
  2. Unit 4: Advanced Data & Memory Management
Structures : Defining Structures and Array of Structures
Unit 4: Advanced Data & Memory Management

1. The Core Idea: struct vs. union

A union is a user-defined data type just like a struct, but it has one *massive* difference in how it stores memory.

·         A struct is an "AND" container. It holds *all* of its members at the same time. A struct Student holds a name *AND* a roll number *AND* a GPA.

·         A union is an "OR" container. It can only hold *one* of its members at any given time. A union Value can hold an int *OR* a float *OR* a char, but never all at once.

Analogy: Toolbox vs. Single Box

struct (Toolbox): A struct is like a large toolbox with separate, labeled compartments. There is a compartment for a hammer, a compartment for a screwdriver, and a compartment for a wrench. All three can be in the toolbox at the same time in their own space.

union (Single Box): A union is like a single, small box. The box is just big enough to hold *either* the hammer, *or* the screwdriver, *or* the wrench. If you put the hammer in, you must take the screwdriver out. All members share the same space.

2. How union Manages Memory

This is the most important part to understand. A struct allocates enough memory to hold *all* its members added together. A union allocates only enough memory to hold its largest member.

All members of a union start at the same memory address.

Let's compare a struct and a union with the same members:

// STRUCT: Total size is AT LEAST 4 + 1 + 8 = 13 bytes

// (plus padding, so maybe 16 bytes)

struct DataStruct {

    int i;     // 4 bytes

    char c;    // 1 byte

    double d;  // 8 bytes

};

 
// UNION: Total size is sizeof(largest_member) = sizeof(double) = 8 bytes

union DataUnion {

    int i;     // Will use the first 4 bytes of the 8-byte block

    char c;    // Will use the first 1 byte of the 8-byte block

    double d;  // Will use all 8 bytes

};

 
int main() {

    printf("Size of struct: %lu bytes\n", sizeof(struct DataStruct));

    printf("Size of union:  %lu bytes\n", sizeof(union DataUnion));

}

Output (typical):

Size of struct: 16 bytes (13 bytes + 3 bytes of padding for alignment)
Size of union: 8 bytes

3. Defining and Using a Union

The syntax for defining and accessing a union is identical to a struct. You use the union keyword and access members with the dot operator (.) or arrow operator (->) for pointers.

The Golden Rule of Unions

You can only safely read from the member that you most recently wrote to. If you write to i and then try to read from d, you will get garbage data. The union has no idea which member is "active" — that is your job as the programmer.

Example: The "Wrong" Way (Causing Data Corruption)

This example shows what happens when you don't follow the golden rule. You are telling C, "Take the bits that represent the integer 123456789 and *pretend* they are a double."

#include <stdio.h>

 
union DataUnion {

    int i;

    char c;

    double d;

};

 
int main() {

    // Create a union variable

    union DataUnion data;

 
    // 1. Write to the integer 'i'

    data.i = 123456789;

    printf("As integer: %d\n", data.i); // OK

    

    // 2. Now read from 'c' and 'd' (DANGEROUS!)

    // This just reads the first byte of 'i'

    printf("As char:    %c\n", data.c); // Garbage

    // This re-interprets the bits of 'i' as a double

    printf("As double:  %f\n", data.d); // Garbage

 
    printf("---\n");

 
    // 3. Now write to the char 'c'

    // This OVERWRITES the first byte of 'i'

    data.c = 'A';

    printf("As char:    %c\n", data.c); // OK

    

    // 4. Read from 'i' again. Its value has been corrupted!

    printf("As integer: %d\n", data.i); // No longer 123456789

 
    return 0;

}

4. Why Use a Union? (Practical Use Case)

Unions are powerful for two main reasons: saving memory and "type punning."

Use Case 1: Saving Memory

Imagine you are creating a data type Value that can hold *either* an integer, a float, or a string. If you used a struct, you would waste a lot of space. A union is perfect.

But how do you know which member is active? You must store that information separately. This is usually done by wrapping the union inside a struct!

This is a very common and important C programming pattern:

#include <stdio.h>

#include <string.h>

 
// 1. Create 'tags' to identify the active type

typedef enum {

    TYPE_INT,

    TYPE_FLOAT,

    TYPE_STRING

} ValueType;

 
// 2. Define the union to hold the data

typedef union {

    int i;

    float f;

    char s[50];

} ValueData;

 
// 3. Wrap them both in a STRUCT

typedef struct {

    ValueType type; // The tag telling us what's active

    ValueData data; // The union holding the actual value

} Value;

 
// 4. Create a function to print the Value safely

void printValue(Value v) {

    switch (v.type) {

        case TYPE_INT:

            printf("Value is an integer: %d\n", v.data.i);

            break;

        case TYPE_FLOAT:

            printf("Value is a float:   %.2f\n", v.data.f);

            break;

        case TYPE_STRING:

            printf("Value is a string:  %s\n", v.data.s);

            break;

    }

}

 
int main() {

    Value v1, v2;

 
    // Create an integer Value

    v1.type = TYPE_INT;

    v1.data.i = 100;

    

    // Create a string Value

    v2.type = TYPE_STRING;

    strcpy(v2.data.s, "Hello World");

 
    // Now we can safely print them

    printValue(v1);

    printValue(v2);

 
    return 0;

}

Use Case 2: Type Punning (Advanced)

Sometimes you *want* to write as one type and read as another. This is an advanced (and often dangerous) technique called "type punning," used to inspect the raw binary representation of a value. For example, to see the bits of a float as an int.

    union TypePun {

        float f;

        unsigned int u; // Must be same size as float (4 bytes)

    };

    

    union TypePun pun;

    pun.f = -12.5;

    

    // This prints the raw IEEE 754 bit pattern for -12.5

    printf("Bits of -12.5 are: 0x%X\n", pun.u);

 

Structures Defining Structures and Array of Structures
Our Products & Services
  • Home
Connect with us
  • Contact us
  • +91 82955 87844
  • Rk6yadav@gmail.com

StudyLover - About us

The Best knowledge for Best people.

Copyright © StudyLover
Powered by Odoo - Create a free website