如果我调用std::make_shared<T>
(而不是仅显式分配shared_ptr<T>
),那么出于性能原因,我希望引用计数在T的实例旁边分配。一切都很好。
但如果我有weak_ptr
个实例引用相同的对象,可能他们需要访问该引用计数,以了解该对象是否仍然存在。
因此,当T的实例的最后一个shared_ptr被销毁时,对系统的天真理解意味着它不能释放存储T的内存,因为weak_ptrs仍然需要访问该计数。
似乎有一个separate weak reference counter并且在理论上可以与T的实例分开保存,这样可以销毁T并释放内存,而弱引用仍然存在。但后来我们又回到了两次单独的分配,挫败了make_shared
的好处。
我认为我在这里误解了一些东西。当存在弱引用时,如何释放为通过std::make_shared
构造的实例分配的内存?
答案 0 :(得分:13)
如果您使用make_shared
并且如果实现对对象和引用计数使用单个分配,则在释放所有引用(强和弱)之前,不能释放该分配。
但是,在释放所有强引用后,对象将被销毁(无论是否仍存在弱引用)。
答案 1 :(得分:3)
常见的实现是std::shared_ptr
的ref控制块分别包含强引用计数和弱引用计数。当强引用计数变为零时,托管对象将被销毁,但仅当弱引用计数也达到零时,才会释放引用控制块本身。
(使用std::make_shared
时,ref控制块本身包含足够的内存来容纳托管对象。这只是一个细节。)
换句话说,托管对象的可观察行为与弱指针无关。