SyntaxStudy
Sign Up
C malloc, realloc, and free
C Beginner 1 min read

malloc, realloc, and free

Dynamic memory allocation lets a program request memory at runtime from the heap rather than the stack. The `malloc()` function (from ``) takes a byte count and returns a `void *` pointer to the allocated block, or `NULL` if allocation fails. You must always check for `NULL` before using the returned pointer. The allocated memory is uninitialised and contains whatever bytes happened to be there. `calloc(n, size)` allocates space for `n` elements of `size` bytes each and zero-initialises the entire block. `realloc(ptr, new_size)` resizes a previously allocated block. If it cannot resize in place, it allocates a new block, copies the data, frees the old block, and returns the new pointer. If `realloc` fails it returns `NULL` but leaves the original block intact — always store the return value in a temporary pointer to avoid losing the original on failure. Every block allocated with `malloc`, `calloc`, or `realloc` must eventually be released with `free()`. Forgetting to call `free()` causes a memory leak — the program holds memory it no longer needs. In a short-lived program this may not matter because the OS reclaims memory on exit, but in long-running servers or embedded systems it is fatal. Calling `free()` on a pointer twice (double-free) is undefined behaviour and can corrupt the heap.
Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Dynamic array: grow on demand */
int main(void)
{
    size_t capacity = 4;
    size_t count    = 0;
    int   *arr      = malloc(capacity * sizeof(int));
    if (!arr) { perror("malloc"); return EXIT_FAILURE; }

    /* Fill beyond initial capacity to trigger realloc */
    for (int i = 0; i < 10; i++) {
        if (count == capacity) {
            capacity *= 2;
            int *tmp = realloc(arr, capacity * sizeof(int));
            if (!tmp) {
                free(arr);           /* don't leak on failure */
                perror("realloc");
                return EXIT_FAILURE;
            }
            arr = tmp;
            printf("Grew to capacity %zu\n", capacity);
        }
        arr[count++] = i * i;
    }

    printf("Array: ");
    for (size_t k = 0; k < count; k++)
        printf("%d ", arr[k]);
    printf("\n");

    /* calloc: zero-initialised */
    int *zeros = calloc(5, sizeof(int));
    if (zeros) {
        printf("calloc zeros: %d %d %d\n", zeros[0], zeros[1], zeros[2]);
        free(zeros);
    }

    free(arr);   /* always free what you malloc */
    return EXIT_SUCCESS;
}