【问题标题】:How to avoid memory leak with shared_ptr?如何使用 shared_ptr 避免内存泄漏?
【发布时间】:2010-12-22 01:33:28
【问题描述】:

考虑下面的代码。

using boost::shared_ptr;
struct B;
struct A{
    ~A() { std::cout << "~A" << std::endl; }
    shared_ptr<B> b;    
};
struct B {
    ~B() { std::cout << "~B" << std::endl; }
    shared_ptr<A> a;
};

int main() {
    shared_ptr<A> a (new A);
    shared_ptr<B> b (new B);
    a->b = b;
    b->a = a;

    return 0;
}

没有输出没有调用析构函数。内存泄漏。 我一直认为智能指针有助于避免内存泄漏。

如果我需要在类中进行交叉引用,我应该怎么做?

【问题讨论】:

    标签: c++ boost memory-leaks shared-ptr smart-pointers


    【解决方案1】:

    如果你有这样的循环引用,一个对象应该持有一个weak_ptr,而不是一个shared_ptr

    来自the shared_ptr introduction

    由于实现使用引用计数,shared_ptr 实例的周期不会被回收。比如main()持有一个shared_ptrA,它直接或者间接持有一个shared_ptrAA的使用次数将是2。销毁原来的shared_ptr将使 A 悬空,使用次数为 1。使用 weak_ptr 来“打破循环”。

    感谢 Glen,提供链接。

    【讨论】:

    • @Alexey,这里是文档的链接,它在介绍中明确警告了这个问题。 boost.org/doc/libs/1_41_0/libs/smart_ptr/shared_ptr.htm
    • 哪一个?为什么不将两者都替换为弱引用呢?这是荒唐的。使用shared_ptr 是有原因的。
    • @curiousguy:我不确定我是否理解你的问题:你觉得什么是荒谬的?要打破循环,必须将一个强引用替换为弱引用;哪一个完全取决于用例。你不能用弱引用替换所有的强引用,因为这样所有的对象都会被销毁,因为没有所有者了。
    • @JamesMcNellis "你觉得什么是可笑的?" 引用可以被非引用替换的想法(称为“弱”引用)。这太疯狂了。
    • @curiousguy 这一点都不疯狂。考虑当 shared_ptr a 和 b 超出范围时,它们都会减少其内部引用计数。计数永远不会达到零,因为彼此之间的计数仍然为 1。析构函数永远不会被调用,因为计数永远不会达到零。他们把对方扣为人质。一个或另一个必须让出所有权;你选择哪一个具有弱参考。这适用于链中更多数量的链接。只是,链条中的一个环节必须很弱才能打破循环依赖。
    猜你喜欢
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2012-10-22
    • 2020-04-23
    相关资源
    最近更新 更多