STL源码剖析之allocator(1)

时间:2022-04-12 05:33:49

空间配置器(allocator)这个概念在阅读源码之前我根本没有听过,原以为内存分配都是使用new和delete运算符(注意和operator new、placement new、operator delete以及placement delete不同)。在实际使用STL编程时也很少会遇到自己去实现一个空间配置器的情况。事实上,STL容器背后都要依靠空间配置器去分配空间。在阅读容器等STL组件的实现之前如果不了解空间配置器的原理,就会造成阅读上的困难。在侯捷的《STL源码剖析》一书中说道:为什么不说allocator是内存配置器而说它是空间配置器呢?因为空间不一定是内存,空间也可以是磁盘或其他辅助介质。但是目前我还没遇到过除内存外的资源配置情况,下文介绍SGI STL中的源码也都是对内存的配置。

根据STL的规范,allocator必须实现以下接口:

allocator::value_type  
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type

定义了用于iterator traits的相关型别,具体到iterator traits技术再介绍。

allocator::rebind

 一个类模板,内部声明了类型other,代表allocator<U>。如果有了allocator<T>,想要allocator<U>和allocator<T>有相同分配策略,那么allocator<U>等同于allocator<T>::rebind<U>::other。

allocator::allocator()
allocator::allocator(
const allocator&)
template
<class U> allocator::allocator(const allocator<U>&)
allocator::
~allocator()

 alllocator的默认构造函数、复制构造函数、带模板的复制构造函数,以及析构函数。

pointer allocator::address(reference x) const    //等同于&x
pointer allocator::address(const_reference x) const //等同于&x

返回对象地址,区别在于传入参数是否是const

void allocator::allocate(size_type n, const void* = 0)

分配空间但不初始化

void allocator::deallocate(pointer p, size_type n)

回收空间

void allocator::max_size() const

返回可成功配置的最大量

void allocator::construct(pointer p, const T& x)

等同于 new ((void *) p) T(x)

void allocator::destroy(pointer p)

等同于 p->~T()

SGI实际使用的配置器为alloc而不是allocator,且不接受任何参数。如果要在程序中使用SGI提供的配置器不能写成类似于

vector<int, std::allocator<int> > iv

而是

vector<int, std::alloc> iv;

说明:在Visual Studio 2017中上面的定义没有什么问题,gcc/g++没有测试过不知道可不可以。第二个vc++肯定不行,g++未知。

SGI STL为每个容器都指定了缺省的空间配置器为alloc,如下面vector的声明:

template<class T, class Alloc = alloc>
class vector { ... };