0

My question is similar to some related questions, but the answers to these questions do not anwer my main confusion. I try to put the question here in its most simple form.

I want to return an array that is defined inside a function body. As C++ does not allow to return an array by value, I declare the function to be returning a pointer.

Why needs this array to be declared static inside the function body in order to be accessible in the main program? I know that local variables are destroyed upon exiting the function body, but the function still returns a pointer to this array, no?

float *doubleEachElement(float *arr)
{
    static float result[3]; // static keyword is necessary
    for (int i = 0; i != 3; i++) result[i] = 2 * arr[i];
    return result;
}

int main()
{
    float a[3] = {1.0, 2.0, 3.5};
    float *a2;
    a2 = doubleEachElement(a);
    for (int i = 0; i!=3; i++) cout << a[i] << " * 2 = " << *(a2+i) << endl;
    // only prints out correctly if the value is declared static inside the function body
    return 0;
}
mr_T
  • 2,571
  • 3
  • 22
  • 39
  • 1
    You should avoid such code. Return some heap allocated data. Preferably return some `std::vector` in C++... – Basile Starynkevitch Sep 01 '14 at 11:01
  • I answered a similar question before - the last option I mention is the one in your question: http://stackoverflow.com/questions/4264304/how-to-return-an-array-from-a-method/4264449#4264449 – Tony Delroy Sep 01 '14 at 11:02
  • 1
    "C++ does not allow to return an array by value" - yes it does, if you wrap it in a class. That's exactly what `std::array` does. – Mike Seymour Sep 01 '14 at 11:03
  • If you know that the array has been destroyed, why do you think that it is valid to use a pointer which used to point to the array before it was destroyed? – M.M Sep 01 '14 at 11:11

4 Answers4

2

In general, you can't return pointers or references to non-static local variables, since they are destroyed when the function returns. Making the array static prevents it from being destroyed, but introduces other problems: the array will be overwritten if you call the function again, and calling it from more than one thread can cause data races.

The good news is that you can return an array by value, if it's wrapped in a class type. C++11 has a standard type for this:

std::array<float, 3> doubleEachElement(float *arr);

If you're stuck in the past, just define your own type, like

struct my_array {
    float values[3];
};
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

Any local variable of a function if it has no static storage duration is not alive after exiting the function. That is it is considered to be destroyed. The memory occupied by the array can be overwrutten. So the pointer will have invalid value and the program will have undefined behaviour.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You answered your own question -

local variables are destroyed upon exiting the function body

so why return pointer to something which is destroyed? This leads to undefined behavior, which you most certainly want to avoid.

To return array from function you should allocate memory using new operator and then return the pointer.

Vinayak Garg
  • 6,518
  • 10
  • 53
  • 80
  • It's best to avoid raw pointers as much as possible. In this case it's much more feasable to return a `std::vector` or `std::array`, or even `std::unique_ptr`. – MatthiasB Sep 01 '14 at 11:10
0

There are three ways how array storage can be allocated:

  • on the stack
  • in the static segment
  • in the heap

(Some variables can be allocated in the CPU registers, but not arrays).

If you declare array inside a function, but does not mark it as static, it will be allocated on the stack. What it means, actually, the compiler will move the stack pointer by the array's size when it calls the function. And be sure it will rewind the stack pointer back when the function returns, making the memory occupied by the array available for the future function calls.

Static memory is allocated at once when you execute your program. And it is not reclaimed until the program is terminated. Hence, if you mark array as static, compiler will reserve the memory in the static segment, so you can safely return its address from the function.

And if you want to allocate something on the heap you need to use malloc/free or new/delete operators. That way you can allocate memory in one place and free it in another. Although, it is even better to use standard containers (like std::vector).

everiq
  • 149
  • 6