简体   繁体   中英

shared pointer and raw pointer lifetime

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?

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
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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM