22

如果我调用std::make_shared<T>(而不仅仅是shared_ptr<T>显式分配),那么出于性能原因,我希望引用计数与 T 的实例一起分配在内存中。一切都很好。

但是,如果我有weak_ptr引用同一个对象的实例,大概他们将需要访问该引用计数,以了解该对象是否仍然存在。

因此,当 T 的实例的最后一个 shared_ptr 被销毁时,对系统的幼稚理解意味着它无法释放存储 T 的内存,因为weak_ptrs 仍然需要访问该计数。

似乎有一个单独的弱引用计数器,理论上可以与 T 的实例分开保存,以便可以在弱引用仍然存在时销毁 T 并释放内存。但随后我们又回到了 2 个单独的分配,阻碍了make_shared.

我想我在这里误解了一些东西。std::make_shared当弱引用存在时,如何释放为通过构造的实例分配的内存?

4

2 回答 2

13

如果您使用make_shared并且如果实现对对象和引用计数使用单个分配,则在释放所有引用(强引用和弱引用)之前无法释放该分配。

但是,对象会在所有强引用被释放后被销毁(不管是否还有弱引用)。

于 2012-11-23T21:20:11.047 回答
3

常见的实现是让 an 的 ref 控制块分别std::shared_ptr包含强引用计数和弱引用计数。当强引用计数变为零时,托管对象被销毁,但是只有当弱引用计数也变为零时,引用控制块本身才被释放。

(当您使用std::make_shared时,ref 控制块本身包含足够的内存来保存托管对象。这只是一个细节。)

换句话说,托管对象的可观察行为独立于弱指针。

于 2012-11-23T21:53:46.503 回答