boost:pool 库备忘

boost::pool 库备忘

boost::pool库使用

Code

#include <functional>
#include <iostream>

#include <boost/pool/pool.hpp>
#include <boost/pool/object_pool.hpp>

namespace xy{
    using namespace std;

    class A{
    public:
        A(){
            cout<<"Construct: "<<endl;
        }
        A(int a){
            cout<<"Construct: "<<a<<endl;
        }
        ~A(){
            cout<<"Destruct"<<endl;
        }
    };

    function< void(void) > f = [](){
        boost::pool< > p{ sizeof(char) };
        void *ptr = p.ordered_malloc(sizeof(A));
        A* a = new (ptr)A();
        a->~A();
    };
    function<void(void)> f_object = [](){
        boost::object_pool< A > p{};
        A *ptr = p.construct(1);
    };
}
int main()
{
    xy::f_object();
}

注意事项

  • f中所用boost::pool可以用来作为一个大内存块反复使用,但需要注意以下几点

  • 构造函数指定大小Chunk_Size,但如果作为通用内存池,设置多大没关系的,一般设置为1字节/sizeof(char)便于分配不同类型/大小的空间(boost::pool内部有对齐机制)。
  • 通过malloc()返回一个构造函数指定大小(Chunk_Size)的块。通过ordered_malloc(n)返回(n*Chunk_Size)大小的块。因此,如果你构造时设置Chunk_Size=1,分配一个类A的对象内存时只需要ordered_malloc(sizeof(A)).如果Chunk_Size>1,分配一个类A的对象内存就需要ordered_malloc(sizeof(A)/Chunk_Size+1)
  • 通过boost::pool来分配不同大小的内存时,需要自己控制使用placement new来调用构造函数 即A* a = new (ptr)A();,显式调用析构函数即a->~A();来析构对象。
  • 通过显式调用free(void * chunk);ordered_free(void * chunk);来返回内存给内存池。当然,不反回给内存池也可以,内存池对象析构时会把内存回收给系统。内存池析构时并不会调用上面的对象的析构函数,因此你总是需要手动调用对象的析构

  • boost::object_pool
  • f_object中所使用的boost::object_pool<T>是指这个内存池中放置的全部都是T类型的对象,如果你通过malloc()来返回一个内存指针,对象的构造函数并未被调用,而通过p.construct(..)来返回的指针是调用了构造函数的。
  • 通过free(T * p);返回内存给内存池时,会调用T的析构函数。
  • 内存池析构时总是会调用每个对象的析构函数。