Reputation: 6749
Could someone explain simply the reason why this does not work:
std::shared_pointer<Bar> getSharedPointer() {
return std::make_shared<Bar>();
}
...
auto foo = getSharedPointer().get();
Apparently using the raw pointer foo
will cause a segfault because the lifetime of the shared pointer returned by getSharedPointer()
will have run out. Somehow I would expect it to last until the end of its scope (like whatever block it is inside).
Is this correct and are there any analogous examples to this situation?
Upvotes: 3
Views: 2072
Reputation: 8268
auto foo = getSharedPointer().get();
Whenever a function returns a type that is not a reference, the result of calling the function is an rvalue. Also, because the function getSharedPointer()
returns a class type, the result is a temporary object.
The lifetime of that temporary object is defined as the end of the evaluation of the outermost expression, here getSharedPointer().get()
. As soon as the foo
variable is initialized, the owning smart pointer is destroyed; when the last shared_ptr
owning that object is destroyed, the object is deleted.
Here getSharedPointer()
always returns shared_ptr
that doesn't share the managed object (use_count()
is 1), so when that copy of the last shared_ptr
is destroyed, the object is destroyed and the pointer to the object is invalid.
(I am not sure why you are returning a shared_ptr
and not a unique_ptr
here.)
The proper use of a smart pointer, or any class that "owns" (controls the lifetime of) other resources (resources that you are still allowed to access directly), is to keep the "smart" pointer/owner alive as long as you need to access the ressource.
So the "smart" pointer (owning object) needs to be named. Also, I am not sure that you really would want to hide the fact that it is a smart pointer from the view of the reader with auto
.
std::shared_pointer<Bar> foo = getSharedPointer();
// use foo.get()
You may want to hide the exact type of managed object:
std::shared_pointer<auto> foo = getSharedPointer();
Upvotes: 2
Reputation: 172924
For getSharedPointer().get();
, getSharedPointer()
returns a temporary std::shared_ptr
which will be destroyed after the expression immediately, and the pointer managed by it will be deleted too. After that foo
will become dangled, any dereference on it causes UB.
auto foo = getSharedPointer().get();
// foo have become dangled from here
You could use a named variable instead:
auto spb = getSharedPointer();
auto foo = spb.get();
// It's fine to use foo now, but still need to note its lifetime
// because spb will be destroyed when get out of its scope
// and the pointer being managed will be deleted too
Upvotes: 8