[STL]源码分析:allocator

本文详细介绍了STL规定的allocator标准及其实现,包括allocator的各种类型定义、构造与析构函数、地址获取、内存分配与释放等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、STL规定的allocator标准

参见侯捷《STL源码剖析》STL规定的allocator标准包含如下功能(方法),当然,并非所有的STL实现版本都严格遵循此标准,因为allocator被STL隐藏,用户一般不直接使用allocator,故而与标准不同也不影响STL的使用。

allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind      // 内部类
allocator::allocator()
allocator::allocator(const allocator &)
template <class U> allocator::allocator(const allocator<U>&)
allocator::~allocator()
pointer allocator::address(reference x) const     	// 传回x的地地,相当于&x,那为什么要搞个函数?
const_pointer allocator::address(const_reference x) const
pointer allocator::allocate(size_type n, const void* = 0)
void allocator::deallocate(pointer p, size_type n)
size_type allocator::max_size() const
void allocator::const(pointer p, const T& x)
void allocator::destroy(pointer p)

二、STLport中对于allocator标准的实现

STLport的allocator位于头文件<_alloc.h>中

template <class _Tp>
class allocator //: public _AllocatorAux<_Tp>
	/* A small helper struct to recognize STLport allocator implementation
	* from any user specialization one.
	*/
	: public __stlport_class<allocator<_Tp> >
继承于__stlport_class<allocator<_Tp>>,没什么大作用,暂不讨论。

1. 一此类型的定义

	typedef _Tp        value_type;
	typedef _Tp*       pointer;
	typedef const _Tp* const_pointer;
	typedef _Tp&       reference;
	typedef const _Tp& const_reference;
	typedef size_t     size_type;
	typedef ptrdiff_t  difference_type;
2. allocator::rebind

#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
	template <class _Tp1> struct rebind {
		typedef allocator<_Tp1> other;
	};
#endif
定义了另一个allocator<_Tp1>

3. 构造函数

allocator() _STLP_NOTHROW {}
默认构造函数。

allocator(const allocator<_Tp>&) _STLP_NOTHROW {}
复制构造函数。

#if defined (_STLP_MEMBER_TEMPLATES)
	template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
#endif
对于模板是另一个类的复制构造函数。

4. 析构函数

~allocator() _STLP_NOTHROW {}
5. allocator::address()

pointer address(reference __x) const {return &__x;}
const_pointer address(const_reference __x) const { return &__x; }
返回了引用参数__x的地址,以指针的形式返回。

6. allocator::allocate()

_Tp* allocate(size_type __n, const void* = 0) {
		if (__n > max_size()) {
			_STLP_THROW_BAD_ALLOC;
		}
		if (__n != 0) {
			size_type __buf_size = __n * sizeof(value_type);
			_Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));	// 实际分配内存
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
			memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
#endif
			return __ret;
		}

		return 0;
	}
此函数分配内存。这里__sgi_alloc = __alloc_type  = __node_alloc。故而调用了__node_alloc::allocate()

class _STLP_CLASS_DECLSPEC __node_alloc {
	static void * _STLP_CALL _M_allocate(size_t& __n);
	/* __p may not be 0 */
	static void _STLP_CALL _M_deallocate(void *__p, size_t __n);

public:
	// this one is needed for proper simple_alloc wrapping
	typedef char value_type;
	/* __n must be > 0      */
	static void* _STLP_CALL allocate(size_t& __n)
	{ return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); }
	/* __p may not be 0 */
	static void _STLP_CALL deallocate(void *__p, size_t __n)
	{ if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); }
};
对于此类,STLport文档给出解释:With a reasonable compiler, this should be roughly as fast as the original STL class-specific allocators, but with less fragmentation。

实际分配内存的函数有两个版本:

一是__stl_new,实际就是new。另一是_M_allocate,由__node_alloc::_M_allocate实现。

void * _STLP_CALL __node_alloc::_M_allocate(size_t& __n)
{ return __node_alloc_impl::_M_allocate(__n); }
此实现位于头文件<allocators.cpp>中,看得出,又被封装了一层。

#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
void* __node_alloc_impl::_M_allocate(size_t& __n) {
  __n = _S_round_up(__n);		// 向上以8字节对齐{ return (((__bytes) + (size_t)_ALIGN-1) & ~((size_t)_ALIGN - 1)); }
  _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
  _Obj *__r;
  // Acquire the lock here with a constructor call.
  // This ensures that it is released in exit or during stack
  // unwinding.
  _Node_Alloc_Lock __lock_instance;
  if ( (__r  = *__my_free_list) != 0 ) {
    *__my_free_list = __r->_M_next;
  } else {
    __r = _S_refill(__n);
  }
#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
  _S_alloc_call();
#  endif
  // lock is released here
  return __r;
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值