I am working with a large object that is stored in a shared memory region, and is returned by a getter. I was running into issues where returning the object by-value was blowing the stack due to the size of the object. To avoid this, I decided to return a unique_ptr
to a copy of the object on the heap, which I want the calling function to be able to use as a local variable. See my example code below:
Note: The codebase I am working on is C++11, not C++14, so I cannot use std::make_unique
#include <memory>
struct AbsoluteUnit {
char bigChungus[10000000];
int bigChungusSize;
};
AbsoluteUnit g_absUnit;
std::unique_ptr<AbsoluteUnit> getAbsoluteUnit() {
return std::move(std::unique_ptr<AbsoluteUnit>(new AbsoluteUnit(g_absUnit)));
}
void Example1()
{
std::unique_ptr<AbsoluteUnit> absUnitPtr = getAbsoluteUnit();
AbsoluteUnit& absUnit = *absUnitPtr.get();
///
/// Some other code
///
}
void Example2()
{
AbsoluteUnit& absUnit = *getAbsoluteUnit().get();
///
/// Some other code
///
}
My question is: In Example2, when does the unique_ptr
go out of scope?
In Example1 I am storing the unique_ptr
in a local variable, so I would expect it to go out of scope when the function exits. But in Example2, I am not creating a local variable for it, so what happens to the unique_ptr
after that line executes? Is it still scoped to the function, or does it immediately go out of scope?
The get()
member function returns the pointer to the AbsoluteUnit
object managed by the std::unique_ptr<AbsoluteUnit>
that getAbsoluteUnit()
returns.
That managed AbsoluteUnit
object is then bound to the reference absUnit
:
AbsoluteUnit& absUnit = *getAbsoluteUnit().get();
However, the std::unique_ptr
ceases to exist just after this statement above, and therefore so does the managed AbsoluteUnit
object. So, absUnit
becomes a dangling reference.
If you want to avoid working with the pointer syntax, you could write instead:
const std::unique_ptr<AbsoluteUnit> ptr = getAbsoluteUnit();
AbsoluteUnit& obj = *ptr;
// ... use obj instead of ptr
or even more concise with auto
:
const auto ptr = getAbsoluteUnit();
auto& obj = *ptr;
// ... use obj instead of ptr