1

I have read this question "Why doesn't C++ support functions returning arrays?". It is said that when we attempt to access the array from outside of this function (via the return value), we have a problem because we are attempting to access memory that is not in the scope with which you are working (the function call's stack).

Doesn't the same problem happen when we return a std::string or std::vector which is declared inside the function or does C++ makes a copy of string or vector and returns the copy to caller so that the string or vector does not go out of scope.

vector<int> foo(const vector<int> a)
{
  vector<int> b = a;
  return b;
} 

int main()
{
   vector<int> a;
   vector<int> c = foo(a);
}
Community
  • 1
  • 1
Raghav
  • 766
  • 16
  • 24

4 Answers4

2

It is making a copy of the std::vector object. The memory the std::vector uses for storing its data is allocated on the heap (and that is also copied).

(Some compiler optimizations mean the copies don't always happen, behind the scenes; e.g. in your sample code, I think most compilers will copy from a to b, inside foo(), but b will become the c in main() rather than be copied again.)

Further Reading: http://en.wikipedia.org/wiki/Copy_elision and http://en.wikipedia.org/wiki/Return_value_optimization (thanks to millsj for the suggestion) Item 20 of More Effective C++, by Scott Meyers, also covers this.

Darren Cook
  • 27,837
  • 13
  • 117
  • 217
2

Yes, in your example, it will call the copy constructor to make a copy, the original copy will go out of scope, but the returned copy will not and can be used to do operations on it, such as assignment to other objects inside main. Since nowadays, compilers do return value optimization RVO or named return value optimization, this cost is minimized.

taocp
  • 23,276
  • 10
  • 49
  • 62
1

Adding to what others already mentioned.

When optimization is ON: NRVO or RVO ensures that a return value is computed in-place rather than copying back to the caller.

When all optimizations are OFF: returning a vector or a string is like returning an object (specifically, a container type object whose size is known to the compiler). Since, the compiler knows about the size of the object being returned, it has enough information to allocate the required stack space for copy-by-value.

If you are attempting to return an array(of any type), how would the compiler know how much size to allocate on stack? Should C++ be forced to return a fixed sized array?

Arun
  • 2,087
  • 2
  • 20
  • 33
  • I have learnt that vector v1 would allocate v1 (header info) on stack and storage of data elements of v1 on heap. Here, would the return object (vector b) be copied on to stack or heap before getting copied to c. Previous answer implied that vector is stored in heap before getting copied. – Raghav Apr 12 '13 at 02:50
  • The vectors internal objects will be on heap (It is only the meta-info or header-info that goes onto stack for a stack based vector). To allocate on stack compiler should know how many objects to create. This information is not available, so the only remaining option is to allocate the memory for the contained object from heap. – Arun Apr 12 '13 at 03:01
  • Have a look at http://stackoverflow.com/questions/15701597/how-does-a-c-stdcontainer-vector-store-its-internals-element-address-acc – Arun Apr 12 '13 at 03:10
1

The returning an object will trigger a copy constructor to have temp vector object which will be assigned to b as copy constructor. The source object will be destroyed after it goes out of scope.

Most modern compilers have an optimization called "Return Value Optimization" (RVO for short). C++11 RValue references allow a vector implementation that guarantees ROV.

shivakumar
  • 3,297
  • 19
  • 28