3

I am trying to return an array from a function:

#include <iostream> using namespace std; int* uni(int *a,int *b) { int c[10]; int i=0; while(a[i]!=-1) { c[i]=a[i]; i++; } for(;i<10;i++) c[i]=b[i-5]; return c; } int main() { int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1}; int b[5]={1,3,4,3,0}; int *c=uni(a,b); for(int i=0;i<10;i++) cout<<c[i]<<" "; cout<<"\n"; return 0; } 

I pass two arrays from my main() into my uni() function. There I create a new array c[10] which I return to my main(). In my uni() function I try to merge the non-negative numbers in the two arrays a and b.

But I get something like this as my output.

1 -1078199700 134514080 -1078199656 -1216637148 134519488 134519297 134519488 8 -1078199700 

Whereas when I try to print the values of c[10] in the uni() function it prints the correct values. Why does this happen?? Is this something related to the stack?? Because I have tried searching about this error of mine, and I found a few places on stackoverflow, where it says that do not allocate on stack but I couldn't understand it.

Further it would become very easy if I allocate my array globally, but if this is the case then everything shall be declared globally?? Why are we even worried about passing pointers from functions?? (I have a chapter in my book for passing pointers)

3
  • If you're using C++, try and use the Standard Library containers like std::array or std::vector. Slinging pointers to C-style arrays back and forth is extremely messy and error-prone. Commented Dec 10, 2014 at 21:17
  • Don not do it, return a std::vector or std::array (note your c[10] is gone after the function returns) Commented Dec 10, 2014 at 21:17
  • You can't return raw arrays. Use a container like tadman suggests (maybe per reference output-parameter). Commented Dec 10, 2014 at 21:19

3 Answers 3

9

Admittedly, the std::vector or std::array approach would be the way to go.

However, just to round things out (and if this is a school project, where the teacher gives you the obligatory "you can't use STL"), the other alternative that will avoid pointer usage is to wrap the array inside a struct and return the instance of the struct.

#include <iostream> using namespace std; struct myArray { int array[10]; }; myArray uni(int *a,int *b) { myArray c; int i=0; while(a[i]!=-1) { c.array[i]=a[i]; i++; } for(;i<10;i++) c.array[i]=b[i-5]; return c; } int main() { int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1}; int b[5]={1,3,4,3,0}; myArray c = uni(a,b); for(int i=0;i<10;i++) cout << c.array[i] << " "; cout << "\n"; return 0; } 

Note that the struct is returned by value, and this return value is assigned in main.

You have the value semantics of returning an instance, plus the struct will get copied, including the array that is internal within it.

Live Example

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

Comments

5

You're returning a pointer to a local object. In the uni function, the variable c is allocated on the stack. At the end of that function, all of that memory is released and in your for loop you are getting undefined results.

As suggested in the comments, std::array or std::vector will give you copy constructors that will allow you to return the object by value as you're trying to do. Otherwise you'll have to resort to something like passing your output array in as an argument.

4 Comments

The copy constructor is not necessary and will likely not be called in a return by value situation.
Thanks.. I dont have much idea about std::array and std::vector, I'll try reading about it. But, this means returning pointers from a function is a useless thing, right??
You can't return a pointer to a stack allocated (locally declared) object. You can dynamically allocate an object with new and return that, or return a pointer to something allocated in some other location.
@Jeffry the copy constructor is likely to be optimized away, but if you delete the copy constructor you won't be able to return the object by value. That said, I concede that "copy constructor" is the wrong way to say that the types have copy semantics.
4

You are returning a pointer to an array that is being deallocated at the return statement. It's a dangling pointer. It's UB.

Use an std::vector or std::array and return by value. There are compiler optimizations that will avoid inefficiencies.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.