allocator详解

vector和内存池

最近看内存池有关的东西,又回顾了一下之前看C++ Primer时自己写的vector,发现只是对基本的Vector的成员函数进行了重写,最重要的地方也就是分配器用的都是默认的,所以内存分配这块之前就没弄清楚。

template >
	class vector
		: public _Vector_alloc<_Vec_base_types<_Ty, _Alloc> >

从STL中vector的源码可以看出,vector分为两个部分,一个是参数类型 _Ty,这里的class跟typename是同一个东西,没有区别;还有一个是分配器 _Alloc,默认是allocator< _Ty >,内存池实现就是在这里,自带的分配器只是简单的new一个内存,vector实现的时候,设立三个指针:

private:
	std::string *elements;				//分配内存的头指针
	std::string	*first_free;			//第一个空闲位置的指针
	std::string *cap;					//开的内存容量指针
	std::allocator alloc;	//分配器

这样简单的判断size==capacity时,重新分配一个大小是原本两倍的内存,再使用移动赋值将原本的数据迁移到新内存中。

分配器allocator

下面的表格是一个分配器所需实现的内存处理成员函数:

成员函数 简介
allocate 分配未初始化的存储 (公开成员函数)
deallocate 解分配存储 (公开成员函数)
construct 在分配的存储构造对象 (公开成员函数)
destroy 析构在已分配存储中的对象 (公开成员函数)

通过实现重载这些成员函数可以实现内存池

allocator::rebind

最近看内存池的实现,发现分配器中有一段代码看不懂:

template  
struct rebind {
    typedef MemoryPool other;
};

这段代码是内存池中,原本的模板变量是T,但是其中又定义了一个U的变量,后来看STL中也都是这么实现的。

原因是这样的:因为内存池分配的时候不仅仅是普通变量,像链表这种还有next指针,所以为了实现这种变量,分配器定义一个other,使用的时候将原本T的普通分配器变换为U的节点分配器,T跟U是有联系的,如下:

template 
struct StackNode_
{
  T data;
  StackNode_* prev;
};

/** T is the object to store in the stack, Alloc is the allocator to use */
template  >
class StackAlloc
{
  public:
    typedef StackNode_ Node;
    typedef typename Alloc::template rebind::other allocator;
  private:
    allocator allocator_;
}

你可能感兴趣的:(allocator详解)