Allocator
Created At :
operator new()和malloc()
- operator new会调用malloc
- 使用malloc进行分配的时候不光会分配相应空间,还会生成一些overhead
allocator的具体实现
- VC的allocator只是以
operator new
和operator delete
来实现用于内存分配的allocate()
和用于回收内存的deallocate()
- BC++的allocator只是以
operator new
和operator delete
来实现用于内存分配的allocate()
和用于回收内存的deallocate()
- GCC的标准allocator只是以
operator new
和operator delete
来实现用于内存分配的allocate()
和用于回收内存的deallocate()
- 没有任何特殊设计
- GUN C没有使用这个空间分配器
//vc6的空间分配器的实现
class allocator{
//...
pointer allocate(size_type _N,const void*)
{
//用allocate分配内存的时候,会调用_Allocate()
return (_Allocate((difference_type)_N,(pointer)0));
}
pointer deallocate(void _FARQ *_P,size_type)
{
//operator delete会调用c的free()
operator delete(_P);
}
};
//...
template<class _Ty> inline
_Ty _FARQ *_Allocate(_PDFT _N,_Ty _FARQ *)
{
if(_N < 0) _N = 0;
//可以看到_Allocate()函数会调用operator new()函数,而operator new就会调用malloc函数
return ((_Ty _FARQ *)operator new((_SIZT)_N * sizeof(_Ty)));
}
// 直接使用allocators来分配和回收空间,需要指定大小,非常难用
int *p = allocator<int>().allocate(512,(int *)0);
allocate<int>().deallocate(p,512);
GUN C 2.9 -allocator
//GUN C中没有使用标准定义的allocator,而是使用的alloc,头文件在<stl_alloc.h>
template <class T,class Alloc = alloc>
class vecotor{
//...
};
- 对于一般情况上,因为malloc申请的内存大小不一定,所以用malloc申请的内存单元需要记录空间大小。
- 但是在容器中,因为容器中的元素大小都是一样的,每次还是用malloc进行分配,将会导致内存空间的浪费。
- stl中的alloc维护了16条链表,每一条链表维护某个固定大小的区块,单向链表。(第i条链表维护$8*(i+1)大小的区块$)
- 对于需要分配的内存区块,会按照8的倍数然后去找对应的大小的链表去申请。(例如申请50byte就会找第6条链表)
- 对于初始化,每条链表会一次性申请一大块内存,然后进行切分。
总结
std::allocator分配器
- SGI标准的空间分配器,它只对operator new和operator delete进行简单封装,运行效率较差。
std::alloc(gun_cxx::pool_alloc)
- 由三部分组成
stl_constrcut.h
定义了全局函数constrcut
和destroy
负责对象的构造和析构
stl_alloc.h
定义了一、二级空间配置器
stl_uninitialized
定义了全局函数,用来填充或复制大块内存数据
STL的两级分配器
- 第一级直接用malloc和free
- 第二级在 < 128b的时候使用内存池,在大于128b的时候调用第一级分配器