0

I'm expecting the code below to print 1 but its printing a random large number. I don't understand why this is happening, please advise.

#include <iostream>
using namespace std;

int * returnArray()
{
    int myArray[5]={1,2,3,4,5};
    return myArray;
}

void printArray(int * myArray)
{
    cout << *myArray<< endl;
}

int main()
{
    printArray(returnArray());
}
James
  • 2,454
  • 1
  • 22
  • 22
coolio
  • 43
  • 2
  • 1
    The array in `returnArray` is being allocated on the stack, the same place as other local variables. When `returnArray` returns, the memory used to hold the array is popped off the stack and is free to be used for other purposes. If you want an array to persist beyond the scope where it was declared, you have to allocate it using `new`. – luqui Aug 10 '11 at 17:10
  • 3
    http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794 <-- So, you rent a hotel room – Billy ONeal Aug 10 '11 at 17:10
  • @Foo Bah Yeah and one could also use brk calls and implement one owns heap, but why not use the standard c++ way to do it? – Voo Aug 10 '11 at 22:47

6 Answers6

5

In your code, returnArray returns a pointer to the first element of myArray, which is local to the function. When the function returns, the memory of its local variables gets released as the call stack is popped, so it can be used for other purposes. In this case, since you call printArray afterwards, the stack area originally occupied by returnArray gets reused for printArray, so the memory that originally contained myArray now has unpredictable content.

As James Kanze pointed out, the best way to accomplish what you want would probably be to use std::vector<int> instead of int*, something like this

std::vector<int> returnArray()
{
    int myArray[5] = { 1, 2, 3, 4, 5 };
    std::vector<int> result(myArray, myArray + 5);
    return result
}

And modify the other functions accordingly to take a vector. Note that in printArray you need myVector[0] to access the first element, as vectors aren't pointers.

JaakkoK
  • 8,247
  • 2
  • 32
  • 50
  • 1
    The cleanest solution would be to return a `std::vector`. That way, the caller gets what he wants, and doesn't have to worry about freeing anything. – James Kanze Aug 10 '11 at 17:20
  • 1
    @jk: The answer is correct but the suggested solution is incorrect, actually kind of evil. Why use array wheh C++ already provides `std::vector`, The suggested solution should be using a `std::vector` and not dynamically allocated array. – Alok Save Aug 10 '11 at 17:25
  • Or you can use a static duration object. – Martin York Aug 10 '11 at 17:26
  • @James, @Als: Yeah, I got too much into the C mindset here. I changed the example to use `std::vector` – JaakkoK Aug 10 '11 at 17:31
2

The function returnArray is effectively returning a pointer to stack data, which will no longer be valid after it returns. The variable myArray[5] is stored on the stack. After the function returns, the stack is used for storing other data. So the value at the address returned has no meaningful value to the calling function.

Mark Wilkins
  • 40,729
  • 5
  • 57
  • 110
2

Because this code causes a Undefined Behavior.
Your array is local to the function and it gets destroyed when the function returns.
Returning a pointer or reference to a local variable in function is Undefined Behavior.

An Undefined Behavior means anything can happen and the behavior cannot be explained. The program might work or may not or even crash, It is not possible to define the results.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

int myArray[] is out of scope when you reference it in the printArray function. That means that the pointer *myArray in printArray() points to some garbage on the stack that is no longer valid.

Tobias Schlegel
  • 3,970
  • 18
  • 22
0

myArray falls out of scope when returnArray returns. In other words, you are returning a pointer to data that is no longer there.

There are a couple of solutions. You could make myArray a global variable, or you could dynamically allocate it, as in

int myArray[5] = new int[5];

If you do this, you'll have to delete it when you no longer need it, using a statement like

delete[] myArray;
kbolino
  • 1,441
  • 2
  • 18
  • 24
0

Change your array object to be permanent.
ie. Make it a static storage duration object. This means it's life span will last longer than the function call/

int * returnArray()
{
    static int myArray[5]={1,2,3,4,5};
  //^^^^^^  
  // a static in function scope means the variable is a static storage duration
  // object. This means its life span is longer than the application (ie it will
  // be tidied up after main exits).
  //
  // Thus it is perfectly valid to return it as the result from the function.

    return myArray;
}

In your version the object was an automatic variable.
This means it ceased to exist after it went out of scope (at the end of the function).

Martin York
  • 257,169
  • 86
  • 333
  • 562