2

I've written the following simple program that sums up the numbers from 0 to 9:

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

int* allocArray() {
    int arr[10];
    return arr;
}

int main(void){
    int* p;
    int summe = 0;
    p = allocArray();
    for(int i = 0; i != 10; ++i) {
        p[i] = i;
    }
    for(int i = 0; i != 10; ++i) {
        summe += p[i];
    }
    printf("Sum = %d\n", summe);
}

The code compiles and delivers the expected result "45". However I get the following warning: 'address of stack memory associated with local variable 'arr' returned'. What am I doing wrong?

4
  • 2
    Does this answer your question? Returning an array using C Commented Jan 22, 2021 at 15:49
  • 1
    Protip: When you get a weird error message, copy and paste the exact text of the error message into the google search box, like this. Chances are, someone else has been puzzled by the same error, and has asked abut it, and gotten answers. Commented Jan 22, 2021 at 15:55
  • Note though that it's a bewilderingly long scroll down that page before someone finally mentions the option of wrapping the array in a struct, which is a perfectly good way to do this while avoiding dynamic allocation (and how C++ implements its properly value-semantic std::array). Commented Jan 22, 2021 at 15:55
  • Same error message: Using C-string gives Warning: "Address of stack memory associated with local variable returned" Commented Oct 22, 2022 at 5:05

2 Answers 2

5

This is undefined behaviour, plain and simple. The only reason it "works" is because with this particular compiler the stack hasn't been trashed yet, but it is living on borrowed time.

The lifetime of arr ends immediately when the function call is complete. After that point any pointers to arr are invalidated and cannot be used.1

Your compiler uses stack memory to store local variables, and the warning indicates that you're returning an address to a now-invalidated stack variable.

The only way to work around this is to allocate memory dynamically and return that:

int* allocArray() {
    int* arr = calloc(10, sizeof(int));

    return arr;
}

Where you're now responsible for releasing that memory later.

You can also use static to extend the lifetime of arr:

int* allocArray() {
    static int arr[10];

    return arr;
}

Though this is not without consequences, either, as now arr is shared, not unique to each function call.


1 Like a lot of things in C there's significant overlap between what you "cannot do" because they lead to undefined behaviour and/or crashes and what you "can do" because it's permitted by the syntax and compiler. It's often your responsibility to know the consequences of any code you write, implied or otherwise.

Sign up to request clarification or add additional context in comments.

4 Comments

Ooops, almost identical answer :)
It is not undefined behavior - it is a kind of "use after free".
@Zuppa, this is literally undefined behavior. The standard states that the lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it... If an object is referred to outside of its lifetime, the behavior is undefined.
@embedded_guy point taken. imho in this case the wording 'undefined behavior' is still a bit weak :)
0

To keep it in your code:

int arr[10];

will allocate the memory on the stack. As soon as you are leaving the function, the content of that array will be overwritten pretty soon. You want to allocate this on the heap.

You would need to use

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

and in the main function, after you've used it (at the end of main), call

delete[] arr;

Nevertheless, this code could be better if the ownership of the array would be properly handled. You want to make yourself familiar with C++ containers and shared/unique pointers.

2 Comments

I think the OP is tagged for C, not C++.
you're right. apart from the C++ containers/pointers hint, the rest is C.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.