Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Calling `.lock()` on weak_ptr returns NULL shared_ptr

I am somewhat confused by the behaviour of the .lock() call on a weak_ptr. My understanding is that .lock() will return a shared_ptr of the relevant type if it has not expired otherwise it will be a null pointer.

From https://en.cppreference.com/w/cpp/memory/weak_ptr/lock :

A shared_ptr which shares ownership of the owned object if std::weak_ptr::expired returns false.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is however not the outcome I am seeing. The code below is a method of the Unit class that should return a shared_ptr to the Unit‘s parent:

unsigned Unit::getParentId() const {
    auto parent = parent_.lock();
    return parent->getId();
}

The debugger output below shows that parent_ exists as a weak_ptr. However when I call auto parent = parent_.lock();, it returns a NULL pointer as can be seen in the last line of the debugger output.

I am obviously missing something really basic here?

this = {const Unit *} 0x16f1af010 
 id_ = {unsigned int} 234
 name_ = {std::string} "Test"
 parent_ = {std::weak_ptr<Unit>} std::__1::weak_ptr<Unit>::element_type @ 0x00006000034d00d8 strong=0 weak=2
  __ptr_ = {std::weak_ptr<Unit>::element_type *} 0x6000034d00d8 
   id_ = {unsigned int} 0
   name_ = {std::string} "Root"
   parent_ = {std::weak_ptr<Unit>} nullptr
   children_ = {std::vector<std::shared_ptr<Unit>>} size=0
 children_ = {std::vector<std::shared_ptr<Unit>>} size=0
parent = {std::shared_ptr<Unit>} nullptr
 __ptr_ = {std::shared_ptr<Unit>::element_type *} NULL

>Solution :

Weak pointer attaches only to existing shared pointers, by itself weak pointer doesn’t hold or create any object pointer. In other words if you do:

std::weak_ptr<int> wp;
auto sp = wp.lock();

then it always returns nullptr. You have to pass Existing shared pointer in constructor or through assignment (=), e.g.

std::shared_ptr<int> sp = std::make_shared<int>();
std::weak_ptr<int> wp(sp);
auto spl = wp.lock(); // now spl is not null

or through assignment

std::shared_ptr<int> sp = std::make_shared<int>();
std::weak_ptr<int> wp;
wp = sp;
auto spl = wp.lock(); // now spl is not null

As long as all copies of shared pointer still exist then weak pointer will return non null on lock. Otherwise if no copies of shared pointer exist then weak pointer will always return null.

In your case you don’t have any copies of shared pointers hence weak pointer will alway return null on lock in such case.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading