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

  • 相关阅读:
    html5传感器
    html5 canvas手写字代码(兼容手机端)
    PHP pdo单例模式连接数据库
    PHP变量回收
    PHP不过过滤防止xss攻击的方法
    jquery监听回车
    jquery预加载显示百分比
    创建自己的代码仓库
    Luxurious Houses
    Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/14546026.html
Copyright © 2011-2022 走看看