1

I already know that a static storage class allows a local variable to keep on existing on the duration of the program.

What I would like to know why it is needed to declare the digits[3] array as static. What happens if I don't declare it as static, other than a compiling error.

P.S. I am quite new in handling pointers or memory addresses in C++.

Although I have a bit of an idea on the stack memory allocation regarding scopes in C++.

int* getDigits(int input)
{
    const int TEN = 10;
    int toStore;
    int digits[3]; /* this array (static) */
    for (int i = 0; i < 3; ++i)
    {   
        toStore = input % TEN;
        digits[i] = toStore;
        input = input / TEN;
    }
    return digits;
}

int main(int argc, char const *argv[])
{
    int* ptr;
    ptr = getDigits(123);
    for (int i = 0; i < 3; ++i)
    {
        std::cout << *( ptr+i ) << std::endl;
    }

    return 0;
}
Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
  • 5
    1. Post all code as text. Images of code are near useless. 2. Why do you think it needs to be static? – Carcigenicate Aug 17 '17 at 13:49
  • 1
    you should be using `std::vector` or `std::array`. If you dont declare it as `static` it will be gone when the function returns and the pointer you return is dangling (ie useless outside of the function) – 463035818_is_not_an_ai Aug 17 '17 at 13:50

2 Answers2

4

You are returning a pointer to an array which is local to the function. If you declare it as static, it means the lifetime of the array extends until the end of the program, so the calling code can dereference the pointer returned from the function. If you do not declare it as static, it is an "automatic" variable whose lifetime ends when the block (function body) ends, and therefore dereferencing a returned pointer to the data is undefined behavior.

In any case, neither of these things is a typical, correct solution. For one thing, if the function is called twice, the second call may change data pointed to by the first result. A more typical solution is to have the function return a pointer (perhaps shared_ptr or unique_ptr) to an array allocated dynamically using new int[3]. Another solution is to have the function create and return a std::array<int, 3>, which is a proper class type which can be returned by value (only C-style arrays cannot be readily returned by value from a function).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 2
    Returning a pointer to a variable of automatic storage duration does not give undefined behaviour. Any attempt to dereference the returned pointer (which is probably the most common thing that might happen in calling code) does though. – Peter Aug 17 '17 at 14:01
3

There are 2 points that the static keyword used on a local variable will influence: lifetime and initialization of a variable.

1. If you would declare a variable non static in a function like:

int* getDigits(int input)
{
   int digits[3]; /* local variable that dies on return */
   ...
   return digits;
}

the array digits is not initialized and it's lifetime is limited to the inner of the function as it's on the stack. If you return from the function the lifetime of the object ends and the access via the returned pointer is undefined, this could and probably will end in a crash of the program.

2. But if you declare the array static like:

int* getDigits(int input)
{
   static int digits[3]; /* local variable that survives return */
   ...
   return digits;
}

it will be zero initialized and it's lifetime will survive the end of the function because it's memory is in the data segment of the program not the stack segment. The pointer that you return will be point to valid memory.


The 1st solution will end in undefined behaviour and the 2nd solution is not optimal as a second call to the getDigits() function would change the static variable digits on wich may a pointer from the first call points to.

It would be better to allocate the memory dynamically with new int[3] or pass the array to be changed as parameter. Moreover there is the possibility to use std::array<int, 3> or std::vector<int>(3) of C++ that would be copied by value. That all would result in new returned variables for several calls of the function.

Andre Kampling
  • 5,476
  • 2
  • 20
  • 47