Memory Stack & Heap

Mastering memory management is what separates C programmers from C users. Learn to allocate, manage, and free memory safely—the foundation of systems programming.

Stack vs Heap

Every program has two main memory regions. Understanding them is fundamental.

Feature Stack Heap
SizeSmall (MBs)Large (GBs)
AllocationAutomaticManual (malloc)
DeallocationAutomatic (Scope End)Manual (free)
SpeedVery FastSlower
LifetimeFunction ScopePersistent until free

Stack Example

void func() { int x = 10; // Stack // Automatically freed }

Heap Example

void func() { int *p = malloc(4); // Heap free(p); // Manual free }

malloc (Memory Allocation)

Allocates a block of uninitialized memory.

malloc.c
// Request 100 integers (400 bytes) int *arr = malloc(100 * sizeof(int)); // ALWAYS check for failure if (arr == NULL) { printf("Allocation failed!\n"); return 1; } // Use memory arr[0] = 10; // Free when done free(arr);

calloc (Contiguous Allocation)

Allocates memory and initializes all bytes to zero. Slightly slower than malloc.

calloc.c
// Allocates 10 ints, initialized to 0 int *arr = calloc(10, sizeof(int)); // arr[0] is guaranteed to be 0 printf("%d", arr[0]); // Prints 0 free(arr);

realloc (Re-Allocation)

Resizes a previously allocated block. Can shrink or expand.

realloc.c
int *arr = malloc(2 * sizeof(int)); // Resize to hold 10 integers int *temp = realloc(arr, 10 * sizeof(int)); if (temp != NULL) { arr = temp; // Successful resize } else { // Resize failed, original arr still valid }

Memory Leaks

Occurs when you allocate memory but forget to free it. The memory remains occupied until the program exits.

The Leak

void leak() { int *p = malloc(100); // Function ends, p is gone // Memory at *p is LOST! }

The Fix

void no_leak() { int *p = malloc(100); // Use p... free(p); // Memory returned }

Dangling Pointers

A pointer that points to memory that has been freed. Dereferencing it causes undefined behavior (crash).

int *p = malloc(sizeof(int)); *p = 10; free(p); // Memory freed // p is now DANGLING. It still holds the address. *p = 20; // DANGEROUS! Use After Free. p = NULL; // SAFE: Mark as invalid immediately.

Advanced Concepts

Fragmentation

Over time, frequent allocations and deallocations leave small gaps in the heap, making it impossible to allocate large contiguous blocks even if total free memory is sufficient.

Double Free

Calling free() on the same pointer twice. This corrupts the heap management data structures and crashes the program.

Debugging with Valgrind

The ultimate tool for detecting memory leaks and errors.

terminal
# Compile with debug info $ gcc -g program.c -o program # Run with Valgrind $ valgrind --leak-check=full ./program ==12345== HEAP SUMMARY: ==12345== in use at exit: 400 bytes in 1 blocks ==12345== total heap usage: 1 allocs, 0 frees ==12345== LEAK SUMMARY: ==12345== definitely lost: 400 bytes in 1 blocks