Search Knowledge

© 2026 LIBREUNI PROJECT

C Programming Mastery / Memory Mastery

Dynamic Memory: The Heap

The Heap: Memory at Runtime

So far, we have used Automatic Storage (local variables on the stack). However, the stack has limitations:

  1. Fixed Size: You must know the size at compile-time (or use VLAs, which are controversial).
  2. Limited Lifetime: Variables die when the function returns.

The Heap is a large pool of memory that exists independently of function calls. We can request memory from the heap at any time and it stays allocated until we explicitly release it.

The Allocation Quadruplet: <stdlib.h>

C provides four primary functions for managing heap memory:

FunctionPurposeKey Detail
malloc(size)Allocates size bytes.Memory is uninitialized (contains garbage).
calloc(n, size)Allocates n elements of size.Memory is zero-initialized.
realloc(ptr, size)Resizes an existing block.May move the block to a new address.
free(ptr)Releases the block.Using the pointer after free is Undefined Behavior.

The Lifecycle of an Allocation

  1. Request: int *p = malloc(10 * sizeof(int));
  2. Safety Check: Always check if malloc returned NULL (which happens if the system is out of memory).
  3. Usage: Use the pointer just like an array.
  4. Cleanup: free(p);
Runtime Environment

Interactive Lab

1#include <stdio.h>
2#include <stdlib.h>
3 
4int main() {
5 int n = 5;
6 int *arr = calloc(n, sizeof(int));
7
8 if (arr == NULL) return 1; // Out of memory
9
10 for(int i = 0; i < n; i++) {
11 arr[i] = i * i;
12 printf("%d ", arr[i]);
13 }
14
15 free(arr);
16 printf("\nMemory freed successfully.\n");
17 return 0;
18}
System Console

Waiting for signal...

The Dangers of Manual Management

In languages like Python or Java, a Garbage Collector cleans up after you. In C, you are the garbage collector.

1. Memory Leaks

A leak occurs when you lose the pointer to an allocated block without calling free(). The memory remains “reserved” but unusable, eventually crashing the system if it happens in a loop.

2. Use-After-Free

Dereferencing a pointer after it has been passed to free(). The memory might have been re-assigned to something else, causing silent data corruption.

3. Double Free

Calling free() on the same pointer twice. This usually crashes the program immediately as it corrupts the heap’s internal metadata.

Interactive Lab

The realloc Pattern

int *p = malloc(10 * sizeof(int));
// We need more space!
int *temp = (p, 20 * sizeof(int));
if (temp != NULL) p = temp;

Memory Fragmentation

Over time, frequent allocations and deallocations can leave “holes” in the heap—small blocks of free memory that are too small to satisfy new requests. High-performance systems often use Custom Allocators (like jemalloc or mimalloc) to mitigate this.