C realloc(), free() & The 4 Deadly Heap Bugs Masterclass

⚑ C (C17 / C23 Standard) 🟒 Lesson 34 πŸ“‚ Phase 13: Dynamic Memory Management πŸ“… 2026 Comprehensive Master Edition
πŸ“Œ Covered in this in-depth guide: realloc() Buffer Expansion Β· Safe Temp Pointer Pattern Β· free() Deallocation Β· Memory Leaks Β· Dangling Pointers Β· Double Free Β· Use-After-Free (UAF)

Welcome to Phase 13 (Chapter 34): C realloc(), free() & The 4 Deadly Heap Bugs Masterclass! Allocating memory is only half the battle. As applications run, dynamic buffers must grow or shrink to fit incoming user data using realloc(), and finished memory blocks must be returned cleanly to the Operating System using free(). However, improper heap management causes the 4 most devastating security vulnerabilities in software history: Memory Leaks, Dangling Pointers, Double Free crashes, and Use-After-Free (UAF) exploits. In this exhaustive textbook-grade guide, you will master safe buffer expansion algorithms, analyze the safe temporary pointer pattern, and learn how to write iron-clad memory-safe code.

1realloc() Mechanics & The Safe Temp Pointer Pattern ⭐

void* realloc(void *ptr, size_t newSize); resizes an existing heap allocation block without losing its existing data. Under the hood, the OS heap manager attempts 2 strategies:

1. In-Place Expansion: If adjacent RAM bytes after the block are free, it simply expands the boundary.
2. Relocation Copy: If adjacent RAM bytes are occupied, it allocates a new larger memory block elsewhere in RAM, copies the old data over, automatically frees the old block, and returns the new memory address!

πŸ›‘ The Fatal realloc() NULL Overwrite Trap:

ptr = realloc(ptr, newSize); // DANGEROUS CODE!
If realloc() fails (returns NULL), assigning NULL directly to ptr overwrites your only pointer reference to the original memory block! The original memory block remains allocated on the heap, but you have lost its addressβ€”creating an unrecoverable Memory Leak!

βœ… The Safe Temp Pointer Blueprint:
void *temp = realloc(ptr, newSize);
if (temp != NULL) { ptr = temp; } else { /* handle error, ptr still valid! */ }

C β€” Safe realloc() Buffer Growth Implementation β–Ά Run Code in C Compiler
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int size = 3;
    int *arr = malloc(size * sizeof(*arr));
    if (arr == NULL) return 1;

    arr[0] = 10; arr[1] = 20; arr[2] = 30;

    // Resizing array from 3 to 5 elements using Safe Temp Pointer Pattern
    int newSize = 5;
    int *temp = realloc(arr, newSize * sizeof(*temp));

    if (temp == NULL) {
        printf("realloc failed! Original buffer preserved.\n");
        free(arr); // Clean up original buffer on exit
        return 1;
    }

    // Success! Update primary pointer reference
    arr = temp;
    arr[3] = 40; arr[4] = 50;

    printf("Resized Array Values: ");
    for (int i = 0; i < newSize; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);
    arr = NULL;
    return 0;
}
2The 4 Deadly Heap Security Bugs & Exploits ⚠️

1. Memory Leak (Unreferenced Heap Bloat)

Allocating heap memory with malloc() but losing the pointer reference without calling free(). Over hours or days, the process consumes all available system RAM until OS kills the process.

2. Dangling Pointer (Stale Reference)

Calling free(ptr) deallocates the memory, but ptr still holds the stale address. Accessing *ptr reads unpredictable garbage memory.
βœ… Remedy: Always set ptr = NULL; immediately after free(ptr);!

3. Double Free (Heap Corruption Crash)

Calling free(ptr) twice on the exact same non-NULL memory address corrupts the OS heap allocator's internal free-list data structure, triggering an immediate security abort (e.g. free(): double free detected).

4. Use-After-Free / UAF (Critical Security Vulnerability)

Attacker exploits a dangling pointer to execute malicious machine code after the original heap block was freed and re-allocated for another purpose (responsible for major CVE exploits in browsers and OS kernels).

3Frequently Asked Questions & Technical Interview Deep-Dive

Q1: What happens if you call free(NULL)?

Standard C specifies that free(NULL) is a safe no-op (does nothing and returns immediately). Grounding pointers to NULL after freeing them prevents accidental Double Free crashes!

Q2: What happens if you call realloc(NULL, size)?

Calling realloc(NULL, size) is 100% equivalent to calling malloc(size)!

πŸ’» Try It Yourself β€” Test realloc Growth in Online C Compiler

Run this dynamic array expander in our live GCC compiler:

C (GCC Standard) β–Ά Open C Compiler
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *buf = malloc(2 * sizeof(*buf));
    if (!buf) return 1;

    buf[0] = 100; buf[1] = 200;

    int *temp = realloc(buf, 4 * sizeof(*buf));
    if (temp) {
        buf = temp;
        buf[2] = 300; buf[3] = 400;
        printf("Expanded Element 3: %d\n", buf[3]);
        free(buf);
        buf = NULL;
    }
    return 0;
}
Open in Online C Compiler β†’