Nicholas
Nicholas

Reputation: 1462

Syntax for converting expired weak_ptr<T> to shared_ptr<T>

From what I've read, a shared_ptr<T> does not get de-allocated until both strong references AND weak references to it are dropped.

I understand a shared object to be considered expired when there are no more strong references to it. The standard lock() function of a weak_ptr<T> therefore fails in such a case because the object is considered 'expired'.

However, if the deleter of a shared pointer is overridden such that the managed object is not deleted, then it should be valid to generated shared_ptr<T> from a weak_ptr<T> - but I cannot find the right syntax to do this.

std::shared_ptr<int> s_ptr(new(42), D());
std::weak_ptr<int) w_ptr(s_ptr);
s_ptr.reset();

s_ptr = std::shared_ptr<int>(w_ptr, false);

EDIT

To clarify this a bit further, I'm trying to construct an object pool of re-usable shared_ptr<T>. The reason behind this is because every use of shared_ptr results in one or more heap memory allocations. So I've added a deleter to every shared_ptr<T> which stores a weak_ptr<T> reference such that then the deleter gets called it should be able to re-add itself to a pool of available shared_ptr<T> objects (with managed object intact). By keeping a weak_ptr<T> stored inside the shared_ptr<T>'s deleter, it therefore shouldn't stop the deleter from being called.

The end goal is to obtain a smart pointer that doesn't do consisant heap allocation - or at least only a small number.

Upvotes: 0

Views: 198

Answers (2)

user1084944
user1084944

Reputation:

If pooling control blocks is a good idea, the library implementation may already be doing it. In fact, the implementation of new itself may already be doing pooling to support similar memory usage patterns.

Furthermore, you can achieve what I think your goals are by using make_shared rather than invoking new and passing it into a shared_ptr constructor; one of the reasons for the existence of this helper function is that it can be written to use a single allocation to allocate both the control block and the new object you're creating at the same time.

Upvotes: 1

Russell Greene
Russell Greene

Reputation: 2281

From what I've read, a shared_ptr does not get de-allocated until both strong references AND weak references to it are dropped.

Wrong. a std::shared_ptr has two blocks - a control block that contains reference counts, etc, then another block for the actual data.

When the shared count goes to 0, the data block is (usually) deallocated. This is why it is illegal to make a std::shared_ptr from a expired std::weak_ptr.

On another note, why would you EVER want this functionality? It ruins the entire point of std::weak_ptr, which is to be able "store" a pointer to a object stored by std::shared_ptr without incrementing its reference count. If you want to do that, then please just use a std::shared_ptr

Upvotes: 1

Related Questions