Skip to content
C Basics: Grow an Allocation Without Losing Its Owner

C Basics: Grow an Allocation Without Losing Its Owner

November 1, 2026

Assigning realloc directly to the only owning pointer can lose the old allocation on failure. Use a temporary pointer and reject invalid sizes before allocating.

Prepare a scratch directory

Tested on Linux x86-64 with GCC 14.2.0. You need GCC, the C development headers, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. This example uses the C standard library and no external package.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1

Run the example

Save this as realloc-ownership-demo.c:

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

static bool resize_values(int **values, size_t count) {
    if (count == 0 || count > SIZE_MAX / sizeof **values) {
        return false;
    }
    int *replacement = realloc(*values, count * sizeof **values);
    if (replacement == NULL) {
        return false;
    }
    *values = replacement;
    return true;
}

int main(void) {
    int *values = NULL;
    if (!resize_values(&values, 2)) {
        fputs("Allocation failed\n", stderr);
        return EXIT_FAILURE;
    }
    values[0] = 10;
    values[1] = 20;
    if (!resize_values(&values, 4)) {
        free(values);
        fputs("Growth failed\n", stderr);
        return EXIT_FAILURE;
    }
    values[2] = 30;
    values[3] = 40;
    printf("Values: %d %d %d %d\n", values[0], values[1], values[2], values[3]);
    printf("Zero count rejected: %s\n", resize_values(&values, 0) ? "no" : "yes");
    printf("First value retained: %d\n", values[0]);
    free(values);
    values = NULL;
    return EXIT_SUCCESS;
}

Compile and run it. The && prevents running an old executable if compilation fails:

gcc -std=c17 -Wall -Wextra -Werror -pedantic realloc-ownership-demo.c -o realloc-ownership-demo &&
./realloc-ownership-demo

Observed output:

Values: 10 20 30 40
Zero count rejected: yes
First value retained: 10

Read the result

For a nonzero requested size, a failed realloc leaves the original allocation available to its owner. On success, retain only the returned pointer. The old contents survive up to the smaller allocation size; initialize newly added elements before reading them.

Apply it carefully

The helper rejects zero to avoid version-specific zero-size behavior and checks multiplication before computing bytes. It accepts NULL initially, which behaves like allocation. A successful reallocation invalidates old aliases, including pointers into the block, even if the numeric address appears unchanged. The example exercises growth and a validation rejection, not an injected out-of-memory failure.

The library reference describes the relevant behavior.

Clean up

Remove only the source and executable created here, then remove the empty scratch directory:

rm -- realloc-ownership-demo.c realloc-ownership-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directory

If the directory is not empty, inspect what remains before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on