• boost的内存管理


    smart_ptr

    • raii ( Resource Acquisition Is Initialization )
    • 智能指针系列的都统称为smart_ptr。包含c++98标准的auto_ptr
    • 智能指针是一个类,通过重载->和*完毕相似原始指针的操作。

      只是由于是类,所以能够做比方内存管理、线程安全之类的工作

    • 智能指针均是自己主动管理内存,不须要显示调用delete

    scoped_ptr

    • 与auto_ptr最大的不同,是私有化构造和拷贝构造,使操作权不能转让,所以有强作用域属性,并且指针类自己负责释放
    • 与c++11标准的unique_ptr相比:unique_ptr有很多其它功能,能够像原始指针一样进行比較、像shared_ptr一样定制删除器,也能够安全地放入标准容器。可是少即是多。scope_ptr专注于强调作用域属性。

    scoped_array

    • 与scoped_ptr相似,仅仅只是封装的是new[]分配数组。
    • 不是指针。也就没有实现*和->的重载,而是直接[]下标訪问
    • 通常不建议使用scoped_array。它的出现通常往往意味着你的代码中存在着隐患

    shared_ptr(重点)

    • boost.smart_ptr中最有价值、最重要的组成部分,也最经经常使用
    • unique()在shared_ptr是指针中唯一全部者时返回true
    • user_count()返回当前指针的引用计数
    • 提供operator<、==比較操作 。使shared_ptr能够被用于set/map标准容器
    • 编写多态指针时。不能使用诸如static_cast< T* >(p.get())的形式。这将导致转型后的指针无法再被shared_ptr正确管理。为了支持这种使用方法,shared_ptr提供内置的转型函数static_pointer_cast< T >()、const_pointer_cast< T >()和dynamic_pointer_cast< T >()
    • 支持operator< < 操作打印指针值,便与调试
    • 有工厂函数
    template< class T, calss... Args >
    shared_ptr< T> make_shared(Args && ... args);
    • 使用代码案例:
    shared_ptr< string > sps(new string("smart"));
    assert(sps->size() == 5);
    shared_ptr< string> sp = make_shared< string > ("make_shared");
    shared_ptr< vector< int >> spv = make_shared< vector< int >> (10,2);
    assert(spv->size() == 10);
    • 应用于标准容器代码案例:
    #include < boost/make_shared.hpp>
    int main()
    {
        typedef vector< shared_ptr< int>> vs;
        vs v(10);
        int i=0;
        for (vs::iterator pos = v.begin(); pos != v.end(); ++pos)
        {
            (*pos) = make_shared< int>(++i);
            cout << *(*pos) << ",";
        }
        cout << endl;
        shared_ptr < int > p = v[9];
        *p = 100;
        cout << *v[9] << endl;
    }

    shared_array

    • 通经常使用shared_ptr< std::vector>或者std::vector< shared_ptr>取代

    weak_ptr(重点)

    • 未重载*和->。最大的作用是协助shared_ptr。观測资源使用情况
    • 代码演示样例:
    int testWeakPtr()
    {
        boost::shared_ptr<int> sp(new int(10));
        assert(sp.use_count() == 1);
    
        boost::weak_ptr<int> wp(sp);
        assert(wp.use_count() == 1);
    
        if (!wp.expired())
        {
            boost::shared_ptr<int> sp2 = wp.lock();
            *sp2 = 100;
            assert(sp2.use_count() == 2);
            assert(wp.use_count() == 2);
        }
    
        assert(wp.use_count() == 1);
        sp.reset();
        assert(wp.expired());
        assert(!wp.lock());
    
        return 0;
    }
    • 作用是打破循环引用,代码演示样例:
    // 循环引用的情形
    class node
    {
    public:
        boost::shared_ptr<node> next;
        ~node()
        {
            cout << "delete node" << endl;
        }
    };
    
    int testWeakPtrRecycleWrong()
    {
        auto n1 = boost::make_shared<node>();
        auto n2 = boost::make_shared<node>();
    
        n1->next = n2;
        n2->next = n1;
    
        assert(n1.use_count() == 2);
        assert(n2.use_count() == 2);
    
        return 0; // 循环引用,析构异常。程序退出时仍未析构
    }
    
    // 避免循环引用的情形,主要就是node里的shared_ptr换成weak_ptr
    class node1
    {
    public:
        boost::weak_ptr<node1> next;
        ~node1()
        {
            cout << "delete node1" << endl;
        }
    };
    
    int testWeakPtrRecycleRight()
    {
        auto n1 = boost::make_shared<node1>();
        auto n2 = boost::make_shared<node1>();
    
        n1->next = n2;
        n2->next = n1;
    
        assert(n1.use_count() == 1);
        assert(n2.use_count() == 1);
    
        if (!n1->next.expired())
        {
            // 调用lock()获得强引用,计数加1
            auto n3 = n1->next.lock();
            assert(n2.use_count() == 2);
        }
        assert(n2.use_count() == 1);
        return 0;
    }

    intrusive_ptr(略)

    pool(pool后缀的都是重点)

    • pool管理内存。仅仅能针对基础类型POD(Plain Old Data),由于不调用对象的构造函数。除非特殊情况。不须要自己释放
    • 调用演示样例代码:
    int testPool()
    {
        pool<> pl(sizeof(int));
        int *p = static_cast<int*>(pl.malloc()); // void*->int*
        assert(pl.is_from(p));
    
        pl.free(p); 
        for (int i = 0; i < 100;i++)
        {
            pl.ordered_malloc(10);
        }
        return 0;
    }

    object_pool

    • pool的子类。实现对类实例(对象)的内存池。会调用析构函数正确释放资源
    • 演示样例代码:
    struct demo_class
    {
    public:
        int a, b, c;
        demo_class(int x = 1, int y = 2, int z = 3) : a(x), b(y), c(z) {}
        ~demo_class()
        {
            cout << "destruct" << endl;
        }
    };
    
    int testObjPool()
    {
        object_pool<demo_class> pl;
        demo_class *p = pl.malloc();
        assert(pl.is_from(p));
    
        // malloc 创建时内存并未初始化
        assert(p->a!= 1 || p->b != 2 || p->c != 3);
    
        p = pl.construct();
    
        // boost自带的construct仅仅能支持3个及以内的參数调用
        p = pl.construct(7, 8, 9); 
        assert(p->a == 7);
    
        object_pool<string> pls;
        for (int i = 0; i < 10; i++)
        {
            string *ps = pls.construct("hello object_pool");
            cout << *ps << endl;
        }
        return 0;
    }

    析构会调用三次。malloc和两次construct均须要调用析构。是object_pool推断出了作用域自己主动调整的。

    singleton_pool

    • 基础类型静态单件(包含基础指针类型)。提供线程安全
    • 演示样例代码
    struct pool_tag{
        int tag;
    };
    typedef singleton_pool<pool_tag, sizeof(pool_tag*)> spl;
    int testSingletonPool()
    {
        pool_tag **p = (pool_tag **)spl::malloc();
        assert(spl::is_from(p));
    
        pool_tag ptag;
        ptag.tag = 3;
        *p = &ptag;
    
        cout << "testSingletonPool : " << (*p)->tag << endl;
        spl::release_memory();
        return 0;
    }

    pool_alloc

    • 提供对标准容器类型的内存分配器,当分配失败时能够抛异常。可是除非特别需求。应该使用stl自带的。假设要用pool_alloc需经过细致測试。保证与容器能够正常工作。

  • 相关阅读:
    python 修改文件内容3种方法
    cv2---imread---error
    when i import skimage,it occurred --"cannot import name '_validate_lengths'"
    centos7 安装jdk8和maven3
    docker pull 速度慢的问题
    jedis.zrangeWithScores 打印值为ASCII码
    git配置多个公钥秘钥问题
    maven 启动tomcat报错:org.apache.jasper.JasperException: Unable to compile class for JSP:
    Yaconf – 一个高性能的配置管理扩展
    java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7168622.html
Copyright © 2020-2023  润新知