zoukankan      html  css  js  c++  java
  • 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需经过细致測试。保证与容器能够正常工作。

  • 相关阅读:
    1026 Table Tennis (30)
    1029 Median
    1025 PAT Ranking (25)
    1017 Queueing at Bank (25)
    1014 Waiting in Line (30)
    1057 Stack (30)
    1010 Radix (25)
    1008 Elevator (20)
    字母大小写转换
    Nmap的基础知识
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7168622.html
Copyright © 2011-2022 走看看