allocator详解

vector和内存池

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

template<class _Ty,
class _Alloc = allocator<_Ty> >
	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<std::string> alloc;	//分配器

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

分配器allocator

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

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

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

allocator::rebind

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

template <typename U> 
struct rebind {
    typedef MemoryPool<U> other;
};

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

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

template <typename T>
struct StackNode_
{
  T data;
  StackNode_* prev;
};

/** T is the object to store in the stack, Alloc is the allocator to use */
template <class T, class Alloc = std::allocator<T> >
class StackAlloc
{
  public:
    typedef StackNode_<T> Node;
    typedef typename Alloc::template rebind<Node>::other allocator;
  private:
    allocator allocator_;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值