boost.pool源码整理和使用说明

Source

#ifndef __KIMI_BOOST_POOL

#define __KIMI_BOOST_POOL

#pragma once

 

 

// std::less, std::less_equal, std::greater

#include <functional>

// new[], delete[], std::nothrow

#include <new>

// std::size_t, std::ptrdiff_t

#include <cstddef>

// std::malloc, std::free

#include <cstdlib>

// std::invalid_argument

#include <exception>

// std::max

#include <algorithm>

 

#include <boost/pool/detail/ct_gcd_lcm.hpp>

#include <boost/pool/detail/gcd_lcm.hpp>

#include <boost/static_assert.hpp>

 

 

namespace kimi_boost

{

 

///声明/

//底层分配策略的两个策略类(policy classes)

struct default_user_allocator_new_delete;

struct default_user_allocator_malloc_free;

 

//管理Block的类(每个Block分为多个Chunk)

template <typename SizeType = std::size_t>

class simple_segregated_storage;

 

//内存池(继承自'class simple_segregated_storage')

template <typename UserAllocator = default_user_allocator_new_delete>

class pool;

 

//对象池(继承自'内存池'),增加了对象的自动构造,析构

template <typename T, typename UserAllocator = default_user_allocator_new_delete>

class object_pool;

 

namespace details

{

//POD代表向系统索要的一大块Block,再加上必要的管理

//PODptr管理一个个Block,形成一个free list

template <typename SizeType>

class PODptr;

};

}//namespace kimi_boost

 

///实现/

namespace kimi_boost

{

//new/delete的分配策略

struct default_user_allocator_new_delete

{

  typedef std::size_t size_type;

  typedef std::ptrdiff_t difference_type;

 

  static char * malloc(const size_type bytes)

  { return new (std::nothrow) char[bytes]; }

  static void free(char * const block)

  { delete [] block; }

};

//malloc/free的分配策略

struct default_user_allocator_malloc_free

{

  typedef std::size_t size_type;

  typedef std::ptrdiff_t difference_type;

 

  static char * malloc(const size_type bytes)

  { return reinterpret_cast<char *>(std::malloc(bytes)); }

  static void free(char * const block)

  { std::free(block); }

};

 

 

namespace details

{

 

template <typename SizeType>

class PODptr

{

public:

       typedef SizeType size_type;

 

private:

    char * ptr;//指向的Block

    size_type sz;//指向的所有Block的字节数

 

    char * ptr_next_size() const

    { return (ptr + sz - sizeof(size_type)); }

 

    char * ptr_next_ptr() const

    {

      return (ptr_next_size() -

          ::boost::details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value);

    }

 

public:

    PODptr(char * const nptr, const size_type nsize)

    :ptr(nptr), sz(nsize) { }

    PODptr()

    :ptr(0), sz(0) { }

 

    bool valid() const { return (begin() != 0); }

    void invalidate() { begin() = 0; }

    char * & begin() { return ptr; }

    char * begin() const { return ptr; }

    char * end() const { return ptr_next_ptr(); }

    size_type total_size() const { return sz; }

    size_type element_size() const

    {

      return (sz - sizeof(size_type) -

                ::boost::details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value);

    }

 

    size_type & next_size() const

    { return *(reinterpret_cast<size_type *>(ptr_next_size())); }

    char * & next_ptr() const

    { return *(reinterpret_cast<char **>(ptr_next_ptr())); }

 

    PODptr next() const

    { return PODptr<size_type>(next_ptr(), next_size()); }

    void next(const PODptr & arg) const

    {

      next_ptr() = arg.begin();

      next_size() = arg.total_size();

    }

};

} // namespace details

 

 

 

 

 

 

 

 

 

template <typename SizeType>

class simple_segregated_storage

{

public:

    typedef SizeType size_type;

 

private:

         //不允许拷贝构造和赋值

    simple_segregated_storage(const simple_segregated_storage &);

    void operator=(const simple_segregated_storage &);

 

    static void * try_malloc_n(void * & start, size_type n,

        size_type partition_size);

 

protected:

    void * first;

    void * find_prev(void * ptr);

       //得到ptr所指向的地址

    static void * & nextof(void * const ptr)

    { return *(static_cast<void **>(ptr)); }

 

public:

    simple_segregated_storage()

    :first(0) { }

    static void * segregate(void * block,

        size_type nsz, size_type npartition_sz,

        void * end = 0);

 

       //nsznpartition_sz的倍数,nszchunk的总字节数,npartition_szchunk的数量

       //block细切,然后把该block加入到free list中的最前面去

    void add_block(void * const block,

        const size_type nsz, const size_type npartition_sz)

    {

      first = segregate(block, nsz, npartition_sz, first);

    }

 

       //nsznpartition_sz的倍数

       //block细切,然后把该block加入到free list中合适的位置上

    void add_ordered_block(void * const block, const size_type nsz, const size_type npartition_sz)

    {

      //找到block应该加入的地方

      void * const loc = find_prev(block);

 

      if (loc == 0)//加入到free list中的最前面

        add_block(block, nsz, npartition_sz);

      else//挂链,加入到free list的中间

        nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc));

    }

 

    bool empty() const { return (first == 0); }

 

       //直接将free list最前面的空闲内存分配

    void * malloc()

       {

              void * const ret = first;

              //调整free list的头指针

              first = nextof(first);

              return ret;

       }

 

    //chunk必须是malloc()函数返回

    //chunk收回,放到free list的头部

    void free(void * const chunk)

    {

              //chunk加入free list的头部

              nextof(chunk) = first;

              first = chunk;

    }

 

       //chunk必须是malloc()函数返回

       //chunk收回,放到free list中合适的位置

    void ordered_free(void * const chunk)

    {

      //找到chunk应该加入的地方

      void * const loc = find_prev(chunk);

      //chunk加入free list中合适的位置

      if (loc == 0)//头部

        free(chunk);

      else

      {//挂链,加入到free list的中间

        nextof(chunk) = nextof(loc);

        nextof(loc) = chunk;

      }

    }

 

    // Note: if you're allocating/deallocating n a lot, you should

    //  be using an ordered pool.

    void * malloc_n(size_type n, size_type partition_size);

 

       //chunks是本对象分配的malloc_n函数分配的空间

       //并且npartition_size两个参数也要一致

       //释放chunks的内存

    void free_n(void * const chunks, const size_type n,

        const size_type partition_size)

    {

      add_block(chunks, n * partition_size, partition_size);

    }

 

       //同上函数

    void ordered_free_n(void * const chunks, const size_type n,

        const size_type partition_size)

    {

      add_ordered_block(chunks, n * partition_size, partition_size);

    }

};

 

 

//函数:simple_segregated_storage::find_prev

 

//遍历free list,返回如果ptr加入到free list,ptr的前一个chunk的位置(按照地址的高低排序)

//返回,表明ptr应该在free list头部

template <typename SizeType>

void * simple_segregated_storage<SizeType>::find_prev(void * const ptr)

{

  //如果free list为空,或者first > ptr,返回(表明ptr应该加在free list头部)

  if (first == 0 || std::greater<void *>()(first, ptr))

    return 0;

 

  void * iter = first;

  while (true)

  {

    if (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr))

      return iter;

 

    iter = nextof(iter);

  }

}

 

 

//函数:simple_segregated_storage::segregate

 

//要求:

//1. npartition_sz >= sizeof(void *)

//2. nsz >= npartition_sz

//3. npartition_sz = sizeof(void *) * i

 

//将一块block细切(block开头,下一个block的开头是end),然后将其挂到end的前面

//blocksz个字节,每个chunkpartition_sz字节

template <typename SizeType>

void * simple_segregated_storage<SizeType>::segregate(

    void * const block,

    const size_type sz,

    const size_type partition_sz,

    void * const end)

{

       //计算出block中最后一个有效的chunk的指针

       //old == block + partition_sz * i

       char * old = static_cast<char *>(block)

              + ((sz - partition_sz) / partition_sz) * partition_sz;

 

       //令它指向下一个block的开头

       nextof(old) = end;

 

       //如果该block只有一个chunk的空间(sz == partition_sz)

       if (old == block) return block;

 

       //从后往前,将这个block中的每个chunk挂链,形成一个单向链表

       for (char * iter = old - partition_sz ; iter != block ; old = iter, iter -= partition_sz)

              nextof(iter) = old;

       nextof(block) = old;

 

       return block;

}

 

 

 

//函数:simple_segregated_storage::try_malloc_n

 

//要求:

//1. n > 0

//2. start != 0

//3. nextof(start) != 0

 

//尝试在free list,start(start不包括)开始,找到n个临近的大小为partition_sizechunk,

//成功返回最后一个chunk的指针.这样,空闲的内存区域为[start,返回值](但是不能使用,因为没有分配)

//失败返回,不分配任何内存.start会被改变为最后一个尝试的chunk块的指针

 

template <typename SizeType>

void * simple_segregated_storage<SizeType>::try_malloc_n(

    void * & start, size_type n, const size_type partition_size)

{

  void * iter = nextof(start);

  while (--n != 0)

  {

    void * next = nextof(iter);

    if (next != static_cast<char *>(iter) + partition_size)

    {

      //next, 或者不连续

      start = iter;

      return 0;

    }

       //iter前进,继续判断

    iter = next;

  }

  return iter;

}

 

//函数:simple_segregated_storage::malloc_n

 

//尝试在free list,start(start不包括)开始,找到n个临近的大小为partition_sizechunk,

//成功返回最后一个chunk的指针.这样,空闲的内存区域为[start,返回值](但是不能使用,因为没有分配)

 

//失败返回,不分配任何内存.

 

template <typename SizeType>

void * simple_segregated_storage<SizeType>::malloc_n(const size_type n,

    const size_type partition_size)

{

       void * start = &first;

       void * iter;

       do

       {

              if (nextof(start) == 0)

                     return 0;

              //注意:并不是死循环,starttry_malloc_n返回时会被改变

              iter = try_malloc_n(start, n, partition_size);

       } while (iter == 0);

 

       void * const ret = nextof(start);

       nextof(start) = nextof(iter);

       return ret;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

template <typename UserAllocator>

class pool: protected simple_segregated_storage<

    typename UserAllocator::size_type>

{

  public:

    typedef UserAllocator user_allocator;

    typedef typename UserAllocator::size_type size_type;

    typedef typename UserAllocator::difference_type difference_type;

 

  private:

    BOOST_STATIC_CONSTANT(unsigned, min_alloc_size =

        (::boost::details::pool::ct_lcm<sizeof(void *), sizeof(size_type)>::value) );

 

    // Returns 0 if out-of-memory

    // Called if malloc/ordered_malloc needs to resize the free list

    void * malloc_need_resize();

    void * ordered_malloc_need_resize();

 

  protected:

    details::PODptr<size_type> list;

    const size_type requested_size;

    size_type next_size;

 

 

    simple_segregated_storage<size_type> & store() { return *this; }//向上转型

    const simple_segregated_storage<size_type> & store() const { return *this; }//向上转型

    details::PODptr<size_type> find_POD(void * const chunk) const;//查找chunk是哪个POD分配的

 

    //判断chunk是否在block i,其中block i中有sizeof_ichunk

    static bool is_from(void * const chunk, char * const i,

        const size_type sizeof_i)

    {

              //i <= chunk < i+sizeof_i

              std::less_equal<void *> lt_eq;

              std::less<void *> lt;

              return (lt_eq(i, chunk) && lt(chunk, i + sizeof_i));

    }

 

    size_type alloc_size() const

    {

              const unsigned min_size = min_alloc_size;

              return ::boost::details::pool::lcm<size_type>(requested_size, min_size);

    }

 

 

    static void * & nextof(void * const ptr)

    { return *(static_cast<void **>(ptr)); }

 

  public:

    // The second parameter here is an extension!

    // pre: npartition_size != 0 && nnext_size != 0

    explicit pool(const size_type nrequested_size,

        const size_type nnext_size = 32)

    :list(0, 0), requested_size(nrequested_size), next_size(nnext_size)

    { }

 

    ~pool() { purge_memory(); }

    bool release_memory();//释放未被分配的block,返回true成功

    bool purge_memory();//释放所有block,返回true成功

 

    // These functions are extensions!

    size_type get_next_size() const { return next_size; }

    void set_next_size(const size_type nnext_size) { next_size = nnext_size; }

 

 

       //所有的分配函数失败时返回

 

       void * malloc()

    {

      // Look for a non-empty storage

              if (!store().empty())

                     return store().malloc();

              return malloc_need_resize();

    }

 

    void * ordered_malloc()

    {

      // Look for a non-empty storage

              if (!store().empty())

                     return store().malloc();

              return ordered_malloc_need_resize();

    }

 

  

    void * ordered_malloc(size_type n);//分配连续的nchunk

 

    //chunk必须是*this.malloc()分配的

    void free(void * const chunk){ store().free(chunk); }

       //同上

    void ordered_free(void * const chunk){ store().ordered_free(chunk); }

       //同上

    void free(void * const chunks, const size_type n)

    {

      const size_type partition_size = alloc_size();//chunk的大小

      const size_type total_req_size = n * requested_size;//总字节数量

      const size_type num_chunks = total_req_size / partition_size +//chunk的数量

          ((total_req_size % partition_size) ? true : false);//为什么不写或者???

 

      store().free_n(chunks, num_chunks, partition_size);

    }

    //同上

    void ordered_free(void * const chunks, const size_type n)

    {

      const size_type partition_size = alloc_size();

      const size_type total_req_size = n * requested_size;

      const size_type num_chunks = total_req_size / partition_size +

          ((total_req_size % partition_size) ? true : false);

 

      store().ordered_free_n(chunks, num_chunks, partition_size);

    }

 

    //判断chunk是否是本对象分配的

    bool is_from(void * const chunk) const

    {

      return (find_POD(chunk).valid());

    }

};

 

 

 

 

 

template <typename UserAllocator>

bool pool<UserAllocator>::release_memory()

{

  bool ret = false;

 

       //block队列上当前和过去的iterator pair

       details::PODptr<size_type> ptr = list;

       details::PODptr<size_type> prev;

 

       //chunk队列上当前和过去的iterator pair

       //注意:prev_free指向的是chunk队列上当前block之前的空闲chunk

       void * free = this->first;

       void * prev_free = 0;

 

       const size_type partition_size = alloc_size();//每个chunk的大小

 

       //遍历搜索所有的已分配的block

       while (ptr.valid())

       {

              if (free == 0)       return ret;

    // At this point:

    //  ptr points to a valid memory block

    //  free points to either:

    //    0 if there are no more free chunks

    //    the first free chunk in this or some next memory block

    //  prev_free points to either:

    //    the last free chunk in some previous memory block

    //    0 if there is no such free chunk

    //  prev is either:

    //    the PODptr whose next() is ptr

    //    !valid() if there is no such PODptr

 

    // If there are no more free memory chunks, then every remaining

    //  block is allocated out to its fullest capacity, and we can't

    //  release any more memory

             

 

    // We have to check all the chunks.  If they are *all* free (i.e., present

    //  in the free list), then we can free the block.

              bool all_chunks_free = true;

 

    // Iterate 'i' through all chunks in the memory block

    // if free starts in the memory block, be careful to keep it there

              void * saved_free = free;

              for (char * i = ptr.begin(); i != ptr.end(); i += partition_size)

              {

      // If this chunk is not free

                     if (i != free)

                     {

        // We won't be able to free this block

                     all_chunks_free = false;

 

        // free might have travelled outside ptr

        free = saved_free;

        // Abort searching the chunks; we won't be able to free this

        //  block because a chunk is not free.

        break;

      }

 

      // We do not increment prev_free because we are in the same block

      free = nextof(free);

    }

 

    // post: if the memory block has any chunks, free points to one of them

    // otherwise, our assertions above are still valid

 

    const details::PODptr<size_type> next = ptr.next();

 

    if (!all_chunks_free)

    {

      if (is_from(free, ptr.begin(), ptr.element_size()))

      {

        std::less<void *> lt;

        void * const end = ptr.end();

        do

        {

          prev_free = free;

          free = nextof(free);

        } while (free && lt(free, end));

      }

      // This invariant is now restored:

      //     free points to the first free chunk in some next memory block, or

      //       0 if there is no such chunk.

      //     prev_free points to the last free chunk in this memory block.

     

      // We are just about to advance ptr.  Maintain the invariant:

      // prev is the PODptr whose next() is ptr, or !valid()

      // if there is no such PODptr

      prev = ptr;

    }

    else

    {

      // All chunks from this block are free

 

      // Remove block from list

      if (prev.valid())

        prev.next(next);

      else

        list = next;

 

      // Remove all entries in the free list from this block

      if (prev_free != 0)

        nextof(prev_free) = free;

      else

        this->first = free;

 

      // And release memory

      UserAllocator::free(ptr.begin());

      ret = true;

    }

 

    // Increment ptr

    ptr = next;

  }

 

  return ret;

}

 

//释放所有已分配的和未分配的内存

template <typename UserAllocator>

bool pool<UserAllocator>::purge_memory()

{

  details::PODptr<size_type> iter = list;

 

  if (!iter.valid())

    return false;

  do

  {

    // hold "next" pointer

    const details::PODptr<size_type> next = iter.next();

    // delete the storage

    UserAllocator::free(iter.begin());

    // increment iter

    iter = next;

  } while (iter.valid());

 

  list.invalidate();

  this->first = 0;

 

  return true;

}

 

 

template <typename UserAllocator>

void * pool<UserAllocator>::malloc_need_resize()

{

       //分配新的区域做block

       const size_type partition_size = alloc_size();//chunk的大小

       const size_type POD_size = next_size * partition_size +//

              ::boost::details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);

 

       //分配空间

       char * const ptr = UserAllocator::malloc(POD_size);

       if (ptr == 0)  return 0;

 

       const details::PODptr<size_type> node(ptr, POD_size);

       next_size <<= 1;//左移位

       //初始化新的空间

       store().add_block(node.begin(), node.element_size(), partition_size);

       //挂链

       node.next(list);

       list = node;

 

       //此时有剩余空间,直接调用分配函数

       return store().malloc();

}

 

template <typename UserAllocator>

void * pool<UserAllocator>::ordered_malloc_need_resize()

{

 

       //分配新的区域做block

       const size_type partition_size = alloc_size();//chunk的大小

       const size_type POD_size = next_size * partition_size +

              ::boost::details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);

 

       //分配空间

       char * const ptr = UserAllocator::malloc(POD_size);

       if (ptr == 0)  return 0;

       const details::PODptr<size_type> node(ptr, POD_size);

       next_size <<= 1;//左移位

 

       //初始化新的空间

       store().add_block(node.begin(), node.element_size(), partition_size);

 

       //找到合适的地方挂链

       if (!list.valid() || std::greater<void *>()(list.begin(), node.begin()))

       {

              node.next(list);

              list = node;

       }

       else

       {

              details::PODptr<size_type> prev = list;

 

              while (true)

              {

                     if (prev.next_ptr() == 0 || std::greater<void *>()(prev.next_ptr(), node.begin()))

                            break;

                     prev = prev.next();

              }

              node.next(prev.next());

              prev.next(node);

       }

       //此时有剩余空间,直接调用分配函数

       return store().malloc();

}

 

template <typename UserAllocator>

void * pool<UserAllocator>::ordered_malloc(const size_type n)

{

       const size_type partition_size = alloc_size();

       const size_type total_req_size = n * requested_size;

       const size_type num_chunks = total_req_size / partition_size +

              ((total_req_size % partition_size) ? true : false);

 

       void * ret = store().malloc_n(num_chunks, partition_size);

       if (ret)    return ret;

 

       //没剩余空间,分配

       using std::max;

       next_size = max <size_type>(next_size, num_chunks);

       const size_type POD_size = next_size * partition_size +

              boost::details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);

       //分配

       char * const ptr = UserAllocator::malloc(POD_size);

       if (ptr == 0)  return 0;

       const details::PODptr<size_type> node(ptr, POD_size);

 

  // Split up block so we can use what wasn't requested

  //  (we can use "add_block" here because we know that

  //  the free list is empty, so we don't have to use

  //  the slower ordered version)

  if (next_size > num_chunks)

    store().add_block(node.begin() + num_chunks * partition_size,

        node.element_size() - num_chunks * partition_size, partition_size);

 

  next_size <<= 1;

 

       //找到合适的地方挂链

  if (!list.valid() || std::greater<void *>()(list.begin(), node.begin()))

  {

    node.next(list);

    list = node;

  }

  else

  {

    details::PODptr<size_type> prev = list;

 

    while (true)

    {

      // if we're about to hit the end or

      //  if we've found where "node" goes

      if (prev.next_ptr() == 0

          || std::greater<void *>()(prev.next_ptr(), node.begin()))

        break;

 

      prev = prev.next();

    }

 

    node.next(prev.next());

    prev.next(node);

  }

 

  //  and return it.

  return node.begin();

}

 

template <typename UserAllocator>

details::PODptr<typename pool<UserAllocator>::size_type>

pool<UserAllocator>::find_POD(void * const chunk) const

{

       // We have to find which storage this chunk is from.

       details::PODptr<size_type> iter = list;

       while (iter.valid())

       {

              if (is_from(chunk, iter.begin(), iter.element_size()))

                     return iter;

              iter = iter.next();

       }

       return iter;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

template <typename T, typename UserAllocator>

class object_pool: protected pool<UserAllocator>

{

  public:

    typedef T element_type;

    typedef UserAllocator user_allocator;

    typedef typename pool<UserAllocator>::size_type size_type;

    typedef typename pool<UserAllocator>::difference_type difference_type;

 

  protected:

    pool<UserAllocator> & store() { return *this; }

    const pool<UserAllocator> & store() const { return *this; }

 

    // for the sake of code readability :)

    static void * & nextof(void * const ptr)

    { return *(static_cast<void **>(ptr)); }

 

  public:

    // This constructor parameter is an extension!

    explicit object_pool(const size_type next_size = 32)

    :pool<UserAllocator>(sizeof(T), next_size) { }

 

    ~object_pool();

 

    // Returns 0 if out-of-memory

    element_type * malloc()

    { return static_cast<element_type *>(store().ordered_malloc()); }

    void free(element_type * const chunk)

    { store().ordered_free(chunk); }

    bool is_from(element_type * const chunk) const

    { return store().is_from(chunk); }

 

    element_type * construct()

    {

      element_type * const ret = malloc();

      if (ret == 0)

        return ret;

      try { new (ret) element_type(); }//placement new

      catch (...) { free(ret); throw; }

      return ret;

    }

 

    // Include automatically-generated file for family of template construct()

    //  functions

#ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS

#   include <boost/pool/detail/pool_construct.inc>

#else

#   include <boost/pool/detail/pool_construct_simple.inc>

#endif

 

    void destroy(element_type * const chunk)

    {

      chunk->~T();

      free(chunk);

    }

 

    // These functions are extensions!

    size_type get_next_size() const { return store().get_next_size(); }

    void set_next_size(const size_type x) { store().set_next_size(x); }

};

 

template <typename T, typename UserAllocator>

object_pool<T, UserAllocator>::~object_pool()

{

  // handle trivial case

  if (!this->list.valid())

    return;

 

  details::PODptr<size_type> iter = this->list;

  details::PODptr<size_type> next = iter;

 

  // Start 'freed_iter' at beginning of free list

  void * freed_iter = this->first;

 

  const size_type partition_size = this->alloc_size();

 

  do

  {

    // increment next

    next = next.next();

 

    // delete all contained objects that aren't freed

 

    // Iterate 'i' through all chunks in the memory block

    for (char * i = iter.begin(); i != iter.end(); i += partition_size)

    {

      // If this chunk is free

      if (i == freed_iter)

      {

        // Increment freed_iter to point to next in free list

        freed_iter = nextof(freed_iter);

 

        // Continue searching chunks in the memory block

        continue;

      }

 

      // This chunk is not free (allocated), so call its destructor

      static_cast<T *>(static_cast<void *>(i))->~T();

      // and continue searching chunks in the memory block

    }

 

    // free storage

    UserAllocator::free(iter.begin());

 

    // increment iter

    iter = next;

  } while (iter.valid());

 

  // Make the block list empty so that the inherited destructor doesn't try to

  //  free it again.

  this->list.invalidate();

}

 

 

}//namespace kimi_boost

 

 

 

 

#endif//__KIMI_BOOST_POOL

Test code

 

void pool_test()

{

       using namespace std;

 

       {

              kimi_boost::object_pool<string> p;

              string* pi[100];

              for (int i = 0; i < 100; ++i)

              {

                     pi[i]= p.construct();

              }

              pi[1]->push_back('d');

              for (int i = 0; i < 100; ++i)

              {

                     p.destroy(pi[i]);

              }

              pi[2]->push_back('a');

 

             

              string* pstring = p.construct();

              bool isfrom = p.is_from(pstring);

              isfrom = p.is_from( pstring + 100 );

              p.destroy(pstring);

       }

       {

              kimi_boost::pool<> p(sizeof(int));

              int* pi[100];

              for (int i = 0; i < 100; ++i)

              {

                     pi[i]= (int*)p.malloc();

              }

 

              for (int i = 0; i < 100; ++i)

              {

                     p.free(pi[i]);

              }

       }

 

 

       {

              kimi_boost::pool<> p(sizeof(char));

              char* pstr = (char*)p.ordered_malloc(20);

              memset(pstr,'/0',20);

              p.ordered_free(pstr,20);

 

       }

}

Output

none

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值