首页 > 代码库 > 遵照std::allocator实现自定制的内存分配器

遵照std::allocator实现自定制的内存分配器

下面是标准库STL中allocator的实现

template<class _Ty>
class allocator
: public _Allocator_base<_Ty>
{ // generic allocator for objects of class _Ty
public:
typedef allocator<_Ty> other;


typedef _Allocator_base<_Ty> _Mybase;
typedef typename _Mybase::value_type value_type;


typedef value_type *pointer;
typedef const value_type *const_pointer;
typedef void *void_pointer;
typedef const void *const_void_pointer;


typedef value_type& reference;
typedef const value_type& const_reference;


typedef size_t size_type;
typedef ptrdiff_t difference_type;


 #if _HAS_CPP0X
typedef false_type propagate_on_container_copy_assignment;
typedef false_type propagate_on_container_move_assignment;
typedef false_type propagate_on_container_swap;


allocator<_Ty> select_on_container_copy_construction() const
{ // return this allocator
return (*this);
}
 #endif /* _HAS_CPP0X */


template<class _Other>
struct rebind
{ // convert this type to allocator<_Other>
typedef allocator<_Other> other;
};


pointer address(reference _Val) const _NOEXCEPT
{ // return address of mutable _Val
return (_STD addressof(_Val));
}


const_pointer address(const_reference _Val) const _NOEXCEPT
{ // return address of nonmutable _Val
return (_STD addressof(_Val));
}


allocator() _THROW0()
{ // construct default allocator (do nothing)
}


allocator(const allocator<_Ty>&) _THROW0()
{ // construct by copying (do nothing)
}


template<class _Other>
allocator(const allocator<_Other>&) _THROW0()
{ // construct from a related allocator (do nothing)
}


template<class _Other>
allocator<_Ty>& operator=(const allocator<_Other>&)
{ // assign from a related allocator (do nothing)
return (*this);
}


void deallocate(pointer _Ptr, size_type)
{ // deallocate object at _Ptr, ignore size
::operator delete(_Ptr);
}


pointer allocate(size_type _Count)
{ // allocate array of _Count elements
return (_Allocate(_Count, (pointer)0));
}


pointer allocate(size_type _Count, const void *)
{ // allocate array of _Count elements, ignore hint
return (allocate(_Count));
}


void construct(_Ty *_Ptr)
{ // default construct object at _Ptr
::new ((void *)_Ptr) _Ty();
}


void construct(_Ty *_Ptr, const _Ty& _Val)
{ // construct object at _Ptr with value _Val
::new ((void *)_Ptr) _Ty(_Val);
}


#define _ALLOC_MEMBER_CONSTRUCT( \
TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, CALL_OPT, X2, X3, X4) \
template<class _Objty COMMA LIST(_CLASS_TYPE)> \
void construct(_Objty *_Ptr COMMA LIST(_TYPE_REFREF_ARG)) \
{ /* construct _Objty(_Types...) at _Ptr */ \
::new ((void *)_Ptr) _Objty(LIST(_FORWARD_ARG)); \
}


_VARIADIC_EXPAND_0X(_ALLOC_MEMBER_CONSTRUCT, , , , )
#undef _ALLOC_MEMBER_CONSTRUCT


template<class _Uty>
void destroy(_Uty *_Ptr)
{ // destroy object at _Ptr
_Ptr->~_Uty();
}


size_t max_size() const _THROW0()
{ // estimate maximum array size
return ((size_t)(-1) / sizeof (_Ty));
}
};


基于上述STL对于内存分配器的实现,如下是基于malloc,free和new,delete对该功能的实现

来自boost中pool的实现版本



#ifndef BOOST_SYS_ALLOCATOR_H
#define BOOST_SYS_ALLOCATOR_H


#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4100)
#endif


// Symbols: malloc_allocator, new_delete_allocator


#include <cstddef>
#include <cstdlib>
#include <boost/limits.hpp>
#include <new>


template <typename T>
struct malloc_allocator
{
  typedef T * pointer;
  typedef const T * const_pointer;
  typedef T & reference;
  typedef const T & const_reference;
  typedef T value_type;


  typedef std::size_t size_type;
  typedef std::ptrdiff_t difference_type;


  template <typename U>
  struct rebind
  {
    typedef malloc_allocator<U> other;
  };


  static pointer address(reference r) { return &r; }
  static const_pointer address(const_reference r) { return &r; }
  static pointer allocate(const size_type n, const void* = 0)
  {
    const pointer ret = (pointer) std::malloc(n * sizeof(T));
    if (ret == 0)
      throw std::bad_alloc();
    return ret;
  }
  static void deallocate(const pointer p, const size_type)
  { std::free(p); }
  static size_type max_size() { return (std::numeric_limits<size_type>::max)(); }


  bool operator==(const malloc_allocator &) const { return true; }
  bool operator!=(const malloc_allocator &) const { return false; }


  malloc_allocator() { }
  template <typename U>
  malloc_allocator(const malloc_allocator<U> &) { }


  static void construct(const pointer p, const_reference t)
  { new ((void *) p) T(t); }
  static void destroy(const pointer p)
  { p->~T(); }
};


template <typename T>
struct new_delete_allocator
{
  typedef T * pointer;
  typedef const T * const_pointer;
  typedef T & reference;
  typedef const T & const_reference;
  typedef T value_type;


  typedef std::size_t size_type;
  typedef std::ptrdiff_t difference_type;


  template <typename U>
  struct rebind
  {
    typedef new_delete_allocator<U> other;
  };


  static pointer address(reference r) { return &r; }
  static const_pointer address(const_reference r) { return &r; }
  static pointer allocate(const size_type n, const void* = 0)
  { return (pointer) new char[n * sizeof(T)]; }
  static void deallocate(const pointer p, const size_type)
  { delete [] p; }
  static size_type max_size() { return (std::numeric_limits<size_type>::max)(); }


  bool operator==(const new_delete_allocator &) const { return true; }
  bool operator!=(const new_delete_allocator &) const { return false; }


  new_delete_allocator() { }
  template <typename U>
  new_delete_allocator(const new_delete_allocator<U> &) { }


  static void construct(const pointer p, const_reference t)
  { new ((void *) p) T(t); }
  static void destroy(const pointer p)
  { p->~T(); }
};


#ifdef _MSC_VER
#pragma warning(pop)
#endif


#endif


通过boost中pool的demo测试代码可以看出这三种的性能在vector中相差无几,、

但是使用boost::fast_pool_allocator在对set和list这样的数据结构中,性能提升了几倍

甚至几十倍。