Dynamic Memory Allocation in C

Dynamic memory allocation allows a program to request and release memory at runtime from the heap (unlike static variables which use stack or data segment).

Essential when:

  • Size of array/structure is not known at compile time
  • Need to create large data structures
  • Want to resize memory during execution
  • Managing memory efficiently in data structures (linked list, trees, graphs)

Four Main Functions for Dynamic Memory

FunctionHeaderPurposeInitializes memory?Returns on failure
malloc()Allocate block of memoryNo (garbage values)NULL
calloc()Allocate + initialize to zeroYes (all bytes 0)NULL
realloc()Resize previously allocated blockPreserves old dataNULL
free()Release allocated memory

1. malloc() - Allocate Memory

C
Dynamic array using malloc
#include <stdio.h>
#include <stdlib.h>

int main() {
    int n;
    printf("Enter number of elements: ");
    scanf("%d", &n);

    int *arr = (int*)malloc(n * sizeof(int));

    if(arr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

    for(int i = 0; i < n; i++) {
        arr[i] = i * 10;
    }

    printf("Array elements: ");
    for(int i = 0; i < n; i++) printf("%d ", arr[i]);

    free(arr);  // Very important!
    arr = NULL; // Good practice

    return 0;
}

2. calloc() - Allocate & Zero-initialize

C
int *matrix = (int*)calloc(5 * 5, sizeof(int));  // 5×5 matrix, all zeros

// Safer than malloc + manual loop to set zeros

3. realloc() - Resize Memory

C
Dynamic growing array
int capacity = 5;
int *arr = (int*)malloc(capacity * sizeof(int));
int count = 0;

// Adding elements...
if(count == capacity) {
    capacity *= 2;
    int *temp = (int*)realloc(arr, capacity * sizeof(int));
    if(temp == NULL) {
        printf("Reallocation failed!\n");
        free(arr);
        return 1;
    }
    arr = temp;
}

// Later when done:
free(arr);
arr = NULL;

4. Common Problems & Dangers

ProblemDescriptionHow to Avoid
Memory LeakForget to call free()Always pair malloc/calloc/realloc with free
Dangling PointerUse pointer after free()Set pointer = NULL after free
Double Freefree() same memory twiceSet pointer = NULL after free
Use after realloc failureContinue using old pointerCheck if realloc returned NULL
Access beyond allocatedOut of boundsKeep track of size/capacity

5. Best Practices (Modern C Style)

  • Always check if allocation succeeded
  • Use `sizeof(*ptr)` instead of type name
  • Prefer `calloc` when you need zero-initialized memory
  • Set pointer to NULL after free
  • Don't cast malloc in C (optional but common)
  • Use tools like Valgrind to detect leaks
  • Modern style (C11+):
  • ```c int *arr = malloc(n * sizeof(*arr)); ```