C++ Returning Reference to Local Variable

C++ Returning reference to local variable

This code snippet:

int& func1()
{
int i;
i = 1;
return i;
}

will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.

int main()
{
int& p = func1();
/* p is garbage */
}

The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.

int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}

int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}

Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.

In either case, you can just return the value itself (although I realize the example you provided was probably contrived):

int func3()
{
return 1;
}

int main()
{
int v = func3();
// do whatever you want with the returned value
}

Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:

class big_object 
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};

big_object func4()
{
return big_object(/* constructor arguments */);
}

int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}

Interestingly, binding a temporary to a const reference is perfectly legal C++.

int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}

Returning reference of local variables in C++ [duplicate]

  1. You should never return a reference or a pointer to a local variable. It will be destroyed right when the function returns. It may appear to work in some cases because the stack may not yet be overwritten. But it will fail unexpectedly eventually.

  2. It is legal to assign a reference to something to a value of the same type. So in your assignment a copy is made.

Return reference to local variable - C++

You can't do it.

Return a copy of the local variable instead.

Because of the magic of C++11 move constructors, this will often be optimized away. I've even seen machine code which removed the move itself and operated as if the function had been passed a pointer to the object receiving the move.

With C++11 and later, it seems best to program as if copies are free. Then profile your code and if there really is a copy problem you can optimize it then.

Return the reference of the local variable [duplicate]

Welcome to undefined behaviour!

That's what you are doing. You access a variable that has gone out of scope. However, it might be that the system hasn't written something over the value that was already there, which explains the behaviour.

That's why finding such logical errors in real code is hard. Because you might be (un)lucky and the variable has the correct value (in that particular execution).

So, f1()'s return value is a reference to something that has gone out of scope, while f2()'s return value is a copy of the local variable of that function, which is OK.


However, a descent compiler should warn you about this, with a warning of this kind:

warning: reference to local variable ‘i’ returned [-Wreturn-local-addr]

Enable your warning flags in your compiler, please. :)



Related Topics



Leave a reply



Submit