Dereferencing a temporary unique_ptr

3.4k views Asked by At
unique_ptr<A> myFun()
{
    unique_ptr<A> pa(new A());
    return pa;
}

const A& rA = *myFun();

This code compiles but rA contains garbage. Can someone explain to me why is this code invalid?

Note: if I assign the return of myFun to a named unique_ptr variable before dereferencing it, it works fine.

2

There are 2 answers

0
masoud On BEST ANSWER

The unique_ptr will pass the ownership to another unique_ptr, but in your code there is nothing to capture the ownership from the returning pointer. In other words, It can not transfer the ownership, so it will be destructed. The proper way is:

unique_ptr<A> rA = myFun(); // Pass the ownership

or

const A rA = *myFun(); // Store the values before destruction

In your code, the returning pointer will be desructed and the reference is refering to an object which is destructing soon, after that using this reference invokes an undefined behavior.

2
kfsone On
unique_ptr<A> myFun()
{
    unique_ptr<A> pa(new A());
    return pa;
}

const A& rA = *myFun();

What you did on that last line:

unique_ptr<A>* temporary = new unique_ptr<A>(nullptr);
myFun(&temporary);
const A& rA = *temporary.get();
delete temporary; // and free *temporary

When you delete temporary it has a contract with you that it owns the pointer and the memory that refers to. So it destructs the A and frees the memory.

Meanwhile, you've sneakily kept a pointer to that memory as a reference to the object at that address.

You could either transfer the pointer to a local unique_ptr:

unique_ptr<A> a = myFun();

or you could copy the objects:

A = *myFun().get();

The 'A' to which myFun()s temporary is only destructed at the close of the statement, so it's present for the copy.