Dynamic Memory Allocation (malloc & free)

⚙️ C Language 🟢 Lesson 16 of 20 📅 2026 Edition
Every variable you've used so far has a size fixed at compile time. Dynamic memory allocation lets your program request additional memory while it's actually running, based on data it doesn't know about until then — essential for building flexible, real-world programs.
1The malloc() Function
C Language ▶ Run Code
#include <stdlib.h>

int *numbers = (int *) malloc(5 * sizeof(int));

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

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

malloc() requests a block of memory of the given size (in bytes) from the heap, and returns a pointer to it — or NULL if the request fails, which you should always check for before using the pointer.

2calloc(): Allocating Zero-Initialized Memory
C Language ▶ Run Code
int *numbers = (int *) calloc(5, sizeof(int));   // allocates AND zeroes out all 5 ints

calloc() works like malloc() but takes two arguments (count and size per element) and guarantees every byte starts at zero — malloc() makes no such guarantee, leaving the memory filled with unpredictable leftover data.

3Freeing Memory with free()
C Language ▶ Run Code
free(numbers);   // returns the memory back to the system
numbers = NULL;  // good practice: avoid an accidental 'dangling pointer'

Every successful malloc() or calloc() call must eventually be matched with exactly one free() call. C has no automatic garbage collector like Python — memory you allocate stays reserved until you explicitly release it.

4realloc(): Resizing Existing Memory
C Language ▶ Run Code
int *numbers = (int *) malloc(5 * sizeof(int));
// ...need more space later...
numbers = (int *) realloc(numbers, 10 * sizeof(int));  // now holds 10 ints, original 5 values preserved

realloc() grows or shrinks a previously allocated block, copying the existing data over automatically. This is how you build dynamic, growable arrays in C.

⚠️ Common Mistake: Memory Leaks: Forgetting to Call free()

Every block of memory you allocate with malloc() or calloc() that you never free() stays reserved for the entire lifetime of your program — this is called a memory leak. In a short practice program this barely matters, but in a long-running real application, repeated leaks gradually consume all available memory and eventually crash the system.

💻 Try It Yourself

Dynamically allocate an array of 5 integers, fill it with values, print them, and properly free the memory afterward.

C Language ▶ Run Code
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = (int *) malloc(5 * sizeof(int));

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

    for (int i = 0; i < 5; i++) {
        arr[i] = (i + 1) * 100;
        printf("%d\n", arr[i]);
    }

    free(arr);
    return 0;
}
Run This in Our Compiler →