• C++的weak_ptr


    在以前的文章中,我们讲过C++的shared_ptr,利用它可以实现基于引用计数的指针回收,从而防止出现内存泄露。
    但是事实上,即使是采用了shared_ptr,在存在循环引用的情况下其实仍然有可能会导致内存泄露,举个例子:

    struct B;
    
    struct A
    {
        std::shared_ptr<B> p;
    };
    
    struct B
    {
        std::shared_ptr<A> p;
    };
    
    int main()
    {
        {
            auto a = std::make_shared<A>();
            auto b = std::make_shared<B>();
            a->p = b;
            b->p = a;
        }
        return 0;
    }
    

    A和B之间相互引用,在大括号中,它们的引用计数为2;即使是被销毁后,引用计数也只是变成了1,不会销毁,这样就出现了内存泄漏。
    为了解决这种循环引用的问题,就需要一种特殊的智能指针:weak_ptr。这种智能指针在指向对象时,对象的引用计数不会+1,所以可以这么实现:

    #include <memory>
    
    struct B;
    
    struct A
    {
        std::weak_ptr<B> p;
    };
    
    struct B
    {
        std::weak_ptr<A> p;
    };
    
    int main()
    {
        {
            auto a = std::make_shared<A>();
            auto b = std::make_shared<B>();
            a->p = b;
            b->p = a;
        }
        return 0;
    }
    

    以上的代码,在大括号内,a和b的引用计数不会因为被weak_ptr指向而增加,因此它们的引用计数始终为1;这样当大括号结束的时候,它们就能被顺利销毁了。我们可以加一个变量查看一下大括号结束时的引用计数:

    int main()
    {
        std::weak_ptr<A> p;
        {
            auto a = std::make_shared<A>();
            auto b = std::make_shared<B>();
            a->p = b;
            b->p = a;
            p = a;
        }
        std::cout << p.use_count() << std::endl;
        return 0;
    }
    
    

    最终的运行结果为0,也就是此时a指向的对象已经被销毁了,不再存在内存泄漏。

  • 相关阅读:
    招标问什么
    其他房产
    长沙
    flume kafka
    http://www.zhihu.com/question/24301047
    38.NOW() 函数
    35.MID() 函数
    36.LEN() 函数
    34.UCASE() LCASE() 函数
    33.HAVING 子句
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/14546026.html
Copyright © 2020-2023  润新知