首页 > 代码库 > STL源码分析--空间配置器的底层实现 (二)

STL源码分析--空间配置器的底层实现 (二)

STL源码分析—空间配置器

空间配置器中门道

在STL中的容器里都是使用统一的空间配置器,空间配置器就是管理分配内存和销毁内存的。在STL将在heap空间创建一个对象分为两个步骤,第一是申请一块内存,第二是在这块内存中初始化一个对象。首先申请空间是由malloc提供,初始化一个对象时由constructor管理。销毁一个对象也是由两步骤完成,第一是销毁空间上的对象,第二是释放这块内存。

同时,STL的空间配置器分为两级内存,如果申请的内存空间大于128KB,那么就使用第一级空间配置,如果小于,那么就从空闲链表中取出一块合适的内存块供使用。

 

STL中空间配置器的名字为alloc,和这个配置器相关的只有两个函数allocate()和deallocate()函数,一个是内存的申请一个是内存的释放,我们不用关心着两个函数的实现,我们只需要知道这两个函数一个对应内存的申请一个对应内存的释放即可。在使用的时候,我们有提供了一个模板封装同时提供了上述两个函数的重载:

Template <class T,class Alloc>

Class simple_alloc{

         Public:

                   StaticT* allocate(size_t n)

{ return 0==n? : (T*)Alloc::allocate(n*sizeof(T)); }

Static T* allocate(void)

{ return 0==n? : (T*)Alloc::allocate(sizeof(T)); }

 

Static void deallocate(T* p,size_t n)

{ if( 0 != n) (T*)Alloc::deallocate(p,n*sizeof(T)); }

 

Static void  allocate(T* p)

{  Alloc::deallocate(p,sizeof(T));}

};

经过这么一个封装,Alloc就可以是STL中的空间配置器,这个类也可以在各个容器中使用了,同时都是static函数,非常方便。

 

除了这两个函数,还有五个函数也非常总要

Constructor()和destroy() 一个是对象的构造一个是读写的销毁。

Uninitialized_copy()

Uninitialized_file()

Uninitialized_fill_n()

这三个函数相当于都是在内存空间上的构造,上述三个函数都是经过萃取,特化后的处理,效率都非常高。所谓萃取就是判断这种类型它的构造拷贝是否为有用的函数,根据这个判读要么使用constructor来构造,要么使用STL上层更加简单的方法。

 

总共有七个函数,七个函数正是空间配置的关键,也是空间配置的上层引用的对外接口,其实STL中的萃取功能非常重要,比如这里的萃取就可以判断对象的使用需要一个一个构造还是需要memmove即可。特化就是将int* char*这些基本的进行特护化。最大可能提供了效率。

 

要明白空间配置器中的constructor函数用到了placement new 的操作。这事New另一种用法

New (p) T(value); 其中p是内存空间的指针,在P指向的空间上构造T类型的对象。平时用到的new都是包括了内存的申请和对象的初始化,但是也有另外一种用法就是在已经存在的内存上构造对象

 

有了空间的申请和销毁,有了对象的构造和销毁,同时又有了大批对象的复制填充,同时利用了C++中的萃取和特化,使得尽可能高的效率,正是这些基本的函数使得上层操作变得简单,变得高效。

STL源码分析--空间配置器的底层实现 (二)