当boost::shared_ptr可能不会被释放?

3
在阅读了这个主题C++面试准备(马特的回答)之后,我对boost::shared_ptr有一个疑问。 shared_ptr是否真的可能会泄漏内存?如何?

1
请参考此链接:https://dev59.com/oHI-5IYBdhLWcg3wfoa1 - Arunmu
1
new boost::shared_ptr<T>(new T()); // o noez! - James McNellis
@James McNellis:不错的例子 :-D - ledokol
{ boost::shared_ptr<T> sp(new T()); std::exit(0); } // o noez! - James McNellis
1
void f(std::shared_ptr<T>, int); 被调用为 f(std::shared_ptr<T>(new T()), (throw 0, 0)); // 可能出错,也可能不出错 - James McNellis
显示剩余2条评论
3个回答

3

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);
  • 使用专用的循环收集器
  • 作为最后的选择,在适当的时候手动置空指针(这会破坏异常安全性)。

谢谢!我从未遇到过这种情况,看起来相当奇怪,最好避免循环。 - ledokol
避免循环确实可以让生活更轻松,但有时它们是必要的,而且有时避免它们比处理它们更费力。 - zwol
是的,但这是一个罕见的情况,需要使用shared_ptr的循环情况更加罕见。weak_ptr看起来是一个不错的解决方案,不过了解专门的循环收集器也是很有趣的事情。 - ledokol

1

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接