什么时候 boost::shared_ptr 可能不会被释放?

Posted

技术标签:

【中文标题】什么时候 boost::shared_ptr 可能不会被释放?【英文标题】:When a boost::shared_ptr might not be freed? 【发布时间】:2011-06-23 21:56:56 【问题描述】:

看完这个话题 C++ interview preparation (马特的回答)我有一个关于 boost::shared_ptr 的问题。 shared_ptr 真的有可能泄漏内存吗?怎么样?

【问题讨论】:

参考这个:***.com/questions/1826902/… new boost::shared_ptr<T>(new T()); // o noez! @James McNellis:很好的例子:-D boost::shared_ptr<T> sp(new T()); std::exit(0); // o noez! void f(std::shared_ptr<T>, int); 称为f(std::shared_ptr<T>(new T()), (throw 0, 0)); // maybe o noez... maybe not 【参考方案1】:

shared_ptr 使用引用计数,这意味着循环引用会导致泄漏。具体来说:

struct A 
    shared_ptr<A> other;
;

shared_ptr<A> foo() 
    shared_ptr<A> one(new A);
    shared_ptr<A> two(new A);
    one->other = two;
    two->other = one;
    return one;

foo 返回的数据结构在没有人工干预的情况下永远不会被释放(将 other 指针中的任何一个设置为 NULL)。

现在这只是每个程序员都应该知道的事实;更有趣的采访对话是如何处理它。选项包括:

重新设计数据结构,因此不需要指针循环; 在每个循环中将至少一个指针降级为非拥有引用(裸指针或weak_ptr); 专用cycle collector; 作为最后的手段,在适当的点手动清空指针(这会破坏异常安全)。

【讨论】:

谢谢!从来没遇到过这种情况,看起来挺奇怪的,最好避免循环。 避免循环确实让生活更轻松,但有时它们是必要的,有时避免它们比处理它们要多得多。 是的,但这是一种罕见的情况,而且循环需要使用 shared_ptr 的情况更加罕见。 Weak_ptr 看起来是一个很好的解决方案,但是阅读有关专用循环收集器的信息会很有趣。【参考方案2】:

循环引用;引用计数垃圾收集器的一个常见问题。

我建议您阅读以下内容:http://www.codeproject.com/KB/stl/boostsmartptr.aspx#Cyclic 参考资料

【讨论】:

【参考方案3】:

shared_ptr 是一种引用计数机制。引用计数的一个问题是您可以拥有一个没有其他人引用的循环引用链。除非有“打破链条”的机制,否则你的链条永远不会被释放。

【讨论】:

以上是关于什么时候 boost::shared_ptr 可能不会被释放?的主要内容,如果未能解决你的问题,请参考以下文章

返回 boost::shared_ptr 和从返回的原始指针构造 boost::shared_ptr 有啥区别?

如何使用 boost::shared_ptr 构造二叉树

为啥 boost shared_ptr 包含带有 close() 的标头?

boost---shared_ptr笔记

在源码树中获取 boost:shared_ptr 的 get 方法的所有使用列表

boost shared_ptr 在更改底层对象时进行复制?