sgi stl的allocate由2級配置器組成, 默認為第二級, 第二級配置器分配內存的時(shí)候, 首先查看需要分配的內存塊大小,如果大于160, 調用第一級配置器, 否則用內存池來(lái)分配內存。 這樣對小塊內存的分配效率高,不容易產(chǎn)生內存碎片。
一級配置器:
template <int __inst>
class __malloc_alloc_template {
二級配置器
template <bool threads, int inst>
class __default_alloc_template {
sgi stl有自己的配置器實(shí)現, 缺省的時(shí)候不使用標準配置器。
以vector為例:
vector的定義:
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class vector : protected _Vector_base<_Tp, _Alloc>
這里__STL_DEFAULT_ALLOCATOR是這樣的一個(gè)東西:
見(jiàn)stl_config.h
# ifndef __STL_DEFAULT_ALLOCATOR
# ifdef __STL_USE_STD_ALLOCATORS
# define __STL_DEFAULT_ALLOCATOR(T) allocator< T >
# else
# define __STL_DEFAULT_ALLOCATOR(T) alloc
# endif
# endif
如果定義了__STL_USE_STD_ALLOCATORS, 那么__STL_DEFAULT_ALLOCATOR 為 allocator<T>, 這個(gè)時(shí)候是標準配置器, 我們可以用自定義的allocator, 否則__STL_USE_STD_ALLOCATORS為alloc, alloc是sgi stl的一個(gè)配置器實(shí)現,這個(gè)時(shí)候即使我們傳入自己的配置器, 也會(huì )被忽略.
最后還有一個(gè)template<class _Tp, class _Allocator>
struct _Alloc_traits {} 并且根據不同的配置器作了特化。只有在定義了__STL_USE_STD_ALLOCATORS的時(shí)候, 才會(huì )定義這個(gè)類(lèi)。
在各個(gè)容器中,使用_Alloc_traits來(lái)萃取當前使用的allocator的實(shí)際類(lèi)型。
如vector:
_Vector_base用來(lái)分配和釋放內存, 并且封裝了標準配置器和sgi配置器的不同。
當沒(méi)有定義__STL_USE_STD_ALLOCATORS, 則使用的是alloc, 不需要_Alloc_traits. 此時(shí)就是確定使用alloc來(lái)分配, 不需要萃取類(lèi)型信息。
_Vector_base
template <class _Tp, class _Alloc>
class _Vector_base {
public:
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Vector_base(const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
_Vector_base(size_t __n, const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
protected:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
typedef simple_alloc<_Tp, _Alloc> _M_data_allocator;
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ _M_data_allocator::deallocate(__p, __n); }
};
如果定義了__STL_USE_STD_ALLOCATORS
template <class _Tp, class _Allocator, bool _IsStatic>
class _Vector_alloc_base {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_data_allocator; }
_Vector_alloc_base(const allocator_type& __a)
: _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{}
protected:
allocator_type _M_data_allocator;
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator.allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ if (__p) _M_data_allocator.deallocate(__p, __n); }
};
// Specialization for allocators that have the property that we don't
// actually have to store an allocator object.
template <class _Tp, class _Allocator>
class _Vector_alloc_base<_Tp, _Allocator, true> {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Vector_alloc_base(const allocator_type&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{}
protected:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
_Tp* _M_allocate(size_t __n)
{ return _Alloc_type::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ _Alloc_type::deallocate(__p, __n);}
};
template <class _Tp, class _Alloc>
struct _Vector_base
: public _Vector_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{
typedef _Vector_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
_Base;
typedef typename _Base::allocator_type allocator_type;
_Vector_base(const allocator_type& __a) : _Base(__a) {}
_Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
};
_Vector_base從_Vector_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>派生。
如果傳入vector的模辦參數_Alloc的類(lèi)型為allocate<_Tp1>, 這是stl_alloc.h里定義的一個(gè)配置器, 封裝了alloc, 實(shí)際分配刪除都調用alloc進(jìn)行。 根據_Alloc_traits的特化, _S_instanceless為true, 而如果_Alloc為自定義配置器,_S_instanceless為false. 當_S_instanceless為true, 則會(huì )使用_Alloc_traits<_Tp, _Allocator>::_Alloc_type作為真正的配置器。typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
_S_instanceless為false, 則使用_Alloc_traits<_Tp, _Allocator>::allocator_type。 這兩個(gè)類(lèi)型在_Alloc_traits中都有定義, 最后,根據配置器的特點(diǎn), vector用萃取出的合適的配置器分配內存。
本文來(lái)自CSDN博客,轉載請標明出處:http://blog.csdn.net/dummyedu/archive/2007/01/08/1477249.aspx
聯(lián)系客服