Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What Happens to a weak_ptr when Its shared_ptr is Destroyed?

It seems that a weak_ptr somehow just knows when the shared_ptr it references has been destroyed. How is that? Is there a constant link maintained or something?

Take the following code for example:

weak_ptr<int> test() {
    shared_ptr<int> foo{new int};

    return foo;
}

int main() {
    auto foo = test();

    cout << foo.expired() << endl;
}

I would have expected a segfault when the weak_ptr<int> goes to check on the state of the shared_ptr<int> but there isn't one. The weak_ptr<int> correctly identifies the memory as deallocated. How does it know?

like image 384
Jonathan Mee Avatar asked Dec 02 '15 16:12

Jonathan Mee


People also ask

What happens when shared_ptr goes out of scope?

The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.

What is the difference between shared_ptr and weak_ptr?

shared_ptr maintains reference count for this propose. when all shared_ptr's pointing to resource goes out of scope the resource is destroyed. A weak_ptr is created as a copy of shared_ptr. It provides access to an object that is owned by one or more shared_ptr instances but does not participate in reference counting.

How can a weak_ptr be turned into a shared_ptr?

To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr constructor or the member function lock.

Does shared_ptr delete?

If you've allocated a shared_ptr dynamically then you're certainly allowed to delete it whenever you want.


1 Answers

A std::shared_ptr is created using two pieces of memory:

  • A resource block: This holds the pointer to the actual underlying data, e.g. 'int*'

  • A control block: This holds information specific to a shared_ptr, for example reference counts.

(Sometimes these are allocated in a single chunk of memory for efficiency, see std::make_shared)

The control block also stores reference counts for weak_ptr. It will not be deallocated until the last weak_ptr goes out of scope (the weak pointer reference count drops to zero).

So a weak_ptr will know that it's expired because it has access to this control block, and it can check to see what the reference count is for a shared_ptr

like image 182
AndyG Avatar answered Oct 17 '22 04:10

AndyG