• 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指向的对象已经被销毁了,不再存在内存泄漏。

  • 相关阅读:
    Ionic Tabs
    Ionic实战九:ionic视频播放
    Ionic实战八:ionic登陆页面源码
    Ionic实战七:Ionic 音乐以及社交页面
    Ionic实战六:日期选择控件
    Ionic实战五:ionic图表源码基于highcharts
    Ionic实战四:ionic 即时通讯_ionic仿雅虎邮箱
    Ionic实战三:Ionic 图片预览可放大缩小左右滑动demo-iClub图片预览
    Ionic实战二:购物车
    编译错误总汇
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/14546026.html
Copyright © 2020-2023  润新知