7

Possible Duplicate:
Returning local data from functions in C and C++ via pointer

I need to create a function with no arguments that returns an array

I get the error: "warning: function returns address of local variable"

my code has been simplified for ease of reading

int * getNums()
{
    int nums[8];
    nums = {1,2,3,4,5,6,7,8};
    return nums;
}

I am led understand that when the function ends the pointer is lost, but will the array still be sent? If not, what is a good way to return this integer array with no arguments in the function call?

Appreciate the help in advance!

Cheers

Community
  • 1
  • 1
Alex
  • 71
  • 1
  • 1
  • 2
  • 1
    Note that [arrays and pointers are not the same](http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c). See also: [How do I use arrays in C++?](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c). – sbi May 03 '11 at 08:30

7 Answers7

7

No, the array will not be "sent". You need to do one of these:

  • create the array dynamically using new
  • create the array statically
  • pass the array into the function as a pointer
  • use std::vector

In most cases, the last is the preferred solution.

5

Pretend you don't know what C-arrays are and join the world of modern C++:

#include <array>
std::array<int, 8> getNums()
{
    std::array<int, 8> ret = {{ 1, 2, 3, 4, 5, 6, 7, 8 }};
    return ret;
}

If your compiler is too old to provide a std:: or std::tr1:: implementation of array<>, consider using boost::array<> instead. Or, consider using std::vector<> either way.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • 2
    If `std/tr1/boost::array` isn't available, then you could return a struct containing the array; that may be more efficient than `std::vector`, particularly for small arrays. – Mike Seymour May 03 '11 at 10:51
3

I am led understand that when the function ends the pointer is lost, but will the array still be sent?

The behavior is undefined.

what is a good way to return this integer array with no arguments in the function call?

int nums[8];

num is local variable which resides on stack. You cannot return the reference of a local variable. Instead alloc nums with operator new and remember to delete[] it.

int* getNums()
{
     int *nums = new int[8] ;
     // .....

     return nums ;
}

// You should deallocate the resources nums acquired through delete[] later,
// else memory leak prevails.
Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • `-1` from me for storing a `new`'d object in a naked pointer. – sbi May 03 '11 at 08:31
  • @sbi - Could you please elaborate your comment so that I can correct. – Mahesh May 03 '11 at 08:34
  • 1
    @Mahesh: Instead of doing manual memory management you can use smart pointers such as `boost::shared_array` in these cases. – Naveen May 03 '11 at 08:36
  • @Naveen - I was just hinting the OP as how to return an array. I am not well acquainted with boost library and any how thanks for your comment. – Mahesh May 03 '11 at 09:14
  • 1
    @Mahesh: the issue is one of resources (memory here) management. Using a naked pointer you put the onus on the caller wrt correctly returning the memory once she's done with it. It is *mandatory* to use a proper resources manager (usually a smart pointer), otherwise you get brittle code (and probably leaky one). In C++03, you'd use a `std::vector`. – Matthieu M. May 03 '11 at 09:43
  • @Matthieu M. - At least I should have hinted OP to use `std::vector` in my answer. I was just thinking in terms of his question and answered. In general, is it advisable for beginners to use `std::vector` at all ? I believe, one should get strong hold as how to manage memory themselves and then start the usage of containers. – Mahesh May 03 '11 at 09:55
  • @Mahesh: Since naked pointers are not to be used in C++, I would say it's rather available to teach *idiomatic* C++ from the start. – Matthieu M. May 03 '11 at 11:23
2

Whenever a function exits all the local variables created within that function get trashed.
You are creating an array local to the function and then returning a pointer to the array. The returned pointer will point to an memory location which is already reclaimed by the OS. So it wont work for you.
Instead of Arrays, You should use vectors, since it is C++

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

You can't return a simple array in C++. Try

int *getNums()
{
    int *nums = new int[8];
    ...
    return nums;
}

Now nums is a pointer to a heap array which will live on after getNums returns.

Daniel Lubarov
  • 7,796
  • 1
  • 37
  • 56
0
int* getNums()
{
    static int nums[8];
    nums = {1,2,3,4,5,6,7,8};
    return nums;
}

It should propabally work now :)

  • Making static increases its lifetime and your done :) –  May 03 '11 at 08:26
  • Hope your app's single-threaded! – ildjarn May 03 '11 at 08:32
  • It might not be obvious to the OP that this is something like a global variable. Even with a single thread you might easily get burned by “creating” two arrays and having the changes in one reflected in the other. – zoul May 03 '11 at 08:43
  • 1
    -1: this solves the immediate problem, sure. However this is a toy example, and real usage suggests that global variables are the shortest road to maintenance hell. – Matthieu M. May 03 '11 at 09:38
0

Your array is a regular stack-based local variable. That means that it disappears when you return from the function and returning a pointer to it does not work. You have to make the array live longer, which can be done by turning it into a static variable or allocating it on the heap:

int *getArray {
    static int foo[] = {…};
    return foo;
}

int *getArray {
    int foo[] = calloc(numberOfItems, sizeof(int));
    foo = …;
    return foo;
}

Both solutions have implications that you should understand before you use one. Namely, the static allocation (first option) is mainly a curiosity nowaydays, since it creates a sort of a global variable and causes more problems than it solves. The heap-allocated array is quite common, but it’s more customary to pass the pointer to fill using an argument to make the interface more explicit. In every case the caller is responsible for freeing the allocated memory later.

And, as others note, there are even better solutions specific to C++, if you don’t insist on using a plain C array.

zoul
  • 102,279
  • 44
  • 260
  • 354
  • Storing a `new`'d object in a naked pointer is a _very_ bad idea, and your warning is not enough to make up for that. – sbi May 03 '11 at 08:32
  • Sorry, I started with a C solution, than noticed the C++ tag and ventured into an unknown territory. I’ll return back to the plain C example I am comfortable with :) Thank you for the correction, what exactly can go wrong in that case? – zoul May 03 '11 at 08:36
  • If you get a naked pointer from a function, you don't know whether you need to deallocate whatever it points to, and if you know, you don't know how. (Is it an object or an array? And was it `new`d or `malloc`'d?) And whenever you juggle with a dumb pointer to a resource you need to cleanup you're not exception-safe. For that you should use smart pointers, preferably off-the-shelf ones like `std::vector` or `std::shared_array`. – sbi May 03 '11 at 11:28