C/C++ Arena

Step 3 of 10

Return heap memory from a function

A function's local variables live in its stack frame, which is destroyed when the function returns. Returning the address of a local is therefore a serious bug:

int *bad(void) {
    int a[3] = {1, 2, 3};
    return a;     // a dies right here
}

The caller gets a dangling pointer: an address that used to hold the array but now belongs to whatever the program does next. It may look fine at first and then show garbage later. Compilers warn: address of stack memory associated with local variable 'a' returned.

Heap memory doesn't have this problem. It lives until someone calls free, so a function can create it and return it safely:

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

int *repeat(int value, int n) {
    int *a = malloc(n * sizeof *a);
    if (a == NULL) {
        return NULL;
    }
    for (int i = 0; i < n; i++) {
        a[i] = value;
    }
    return a;
}

int main(void) {
    int *sevens = repeat(7, 3);
    if (sevens == NULL) {
        return 1;
    }
    printf("%d %d %d\n", sevens[0], sevens[1], sevens[2]);
    free(sevens);
    return 0;
}
7 7 7

Ownership moves to the caller

repeat allocates, but it's main that frees. The responsibility for freeing is called ownership, and here it passes from the function to its caller along with the pointer. C doesn't track this for you, so it has to be clear from the function's name and documentation that "the caller must free the result".

If the allocation fails, returning NULL passes the problem up to the caller, who is in the best position to decide what to do.

Your turn: write int *range(int n) returning a new heap array {0, 1, ..., n-1}.

Previous: Size decided at runtime Next: calloc and strdup-style copies