首页 > 代码库 > 遵照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这样的数据结构中,性能提升了几倍
甚至几十倍。