Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do std::weak_ptrs affect when the memory allocated by std::make_shared is deallocated?

Tags:

c++

memory

If I call std::make_shared<T> (rather than just allocating a shared_ptr<T> explicitly) then I expect the reference count to be allocated in memory alongside the instance of T, for performance reasons. All well and good.

But if I have weak_ptr instances referencing the same object, presumably they will need access to that reference count, to know whether the object still exists.

So, when the last shared_ptr to the instance of T is destroyed, a naive understanding of the system would imply that it cannot deallocate the memory that T is stored in, because weak_ptrs still require access to that count.

It seems like there is a separate weak reference counter and in theory that could be held separately from the instance of T, so that the T can be destroyed and the memory deallocated while weak references still exist. But then we're back to having 2 separate allocations, thwarting the benefits of make_shared.

I assume I am misunderstanding something here. How can the memory allocated for a instance constructed via std::make_shared be freed when weak references exist?

like image 834
Kylotan Avatar asked Nov 23 '12 21:11

Kylotan


2 Answers

If you use make_shared and if the implementation uses a single allocation for both the object and the reference counts, then that allocation cannot be freed until all references (both strong and weak) have been released.

However, the object will be destroyed after all strong references have been released (regardless of whether there are still weak references).

like image 187
James McNellis Avatar answered Nov 13 '22 20:11

James McNellis


The common implementation is for the ref control block of an std::shared_ptr to contain both a strong and a weak reference count separately. The managed object is destroyed when the strong reference count goes to zero, but the ref control block itself is only released when the weak reference count also reaches zero.

(When you use std::make_shared, the ref control block itself contains enough memory to hold the managed object. This is just a detail.)

In other words, the observable behaviour for the managed object is independent of weak pointers.

like image 26
Kerrek SB Avatar answered Nov 13 '22 18:11

Kerrek SB