Reputation: 38919
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?
Upvotes: 13
Views: 2179
Reputation: 41092
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
Upvotes: 15