00 写在前面
在前面对于vector的分析中,我们遇到了allocator
template<class T,class Alloc=alloc>
分配器是贯穿所有容器的存在,即使我们在使用各个容器时并不会用到它,但在背后的空间配置都是分配器的功劳。
这次让我们读懂allocator的原理,帮助我们更好地理解STL。
01 malloc()
所有的分配在最终都会走到malloc()
在c++的层面上也就是operator new(),其底层也是调用了malloc()
你所要的大小只有fill这么大,但malloc会搭配一些其他必要的东西。
所以这就意味着申请空间越大,附加东西比例越小,申请空间小则占用比例越大。
02 概述
再回到allocator的实现,那么allocator的底层也应该是由malloc()支撑的。
先看一个VC的版本:
观察allocator类
class alloctor{
...
pointer allocate(size_type n,const void *)
{return (Allocate((difference_type) n,(pointer)0));}
void deallocate(pointer p,size_type n)
{operator delete(p)}
}
allocate调用了Allocate
再看Allocate
template <class T>inline
...Allocate(...){
return ...operator new(...)
}
也就说明VC中allocator底层就是使用malloc()和free()实现的。
-
先说说为什么allocator我们不常用
因为在分配和释放空间时,都需要声明多少个元素,分配时可定义,但释放时一般不会记得,所以比较难用。
-
像VC的这种实现方法也会引出一个问题:当元素很小但很多时,额外开销不会很大?
当然是会的。这样就会导致额外开销很大,在这种情况下浪费大量空间。
03 SGI STL中的alloc
在SGI STL中的配置器解决了我们上面提到的这个问题。它也与标准的规范不同,其他分配器使用allocator,而SGI STL中的命名为alloc。
而且不接受任何参数。
比如标准写法为:
vector<int,std::alloctor<int>>iv;
但使用SGI STL allocator就要这样写:
vector<int,std:alloc>iv;
虽然没能符合标准,但是实际使用起来问题不大,因为在底层都会自行指定分配器&#x