一般我们在使用STL的时候,空间配置器allocator对于我们是隐藏的。它隐藏在容器之后,进行空间内存的分配、管理、释放等工作。整个STL的操作对象都存放在容器之内,而容器需要配置空间来存放内容,这个时候,空间配置器就派上作用了。
将allocator称之为空间配置器的原因是,空间不一定是内存,也可能是磁盘或其他存储介质。allocator可以向内存获得空间,也可以向硬盘取得空间。
STL的配置器(allocator)定义在头文件memory中,其中包括了三个重要的头文件:
1、<stl_construct.h> : 这里面定义了全局函数construct()和destroy(),负责对象的构造和析构。
2、<stl_alloc.h> :定义了一、二级配置器,彼此合作。配置器名为alloc。
3、<stl_uninitialized.h>:定义了一些全局函数,用来填充(fill)或复制(copy)大块内存数据。
std::alloc中的双层级配置器
第一层级配置器直接使用malloc()和free(),第二级配置器视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器;当配置区块小于128bytes时,视之为“过小”,为了降低额外负担,便采用复杂的内存池整理方式,而不再求助于第一级配置器。
二级配置器的做法是,如果区块足够大,超过128bytes时,就移交第一级配置器处理。当区块小于128bytes时,则以内存池管理,此法又称为次层配置:每次配置一大块内存,并维护对应的自由链表。下次若再有相同大小的内存需求,就直接从自由链表中拨出。如果有小额区块被释放,就由配置器回收到自由链表中,也就是说,配置器除了负责配置,也负责回收。为了方便管理,第二级配置器会主动将任何小额区块的内存需求量上调至8的倍数。
空间配置函数allocate()
allocate()函数首先会判断区块大小,大于128bytes就调用第一级配置器,小于128bytes就检查对应的free list。如果free list之内有可用的区块,就直接拿来用,如果没有可用的区块,就将区块大小上调至8倍数边界,然后调用refill()函数,准备为free list重新填充空间。
空间释放函数deallocate()
该函数首先判断区块大小,大于128bytes就调用第一级配置器,小于128bytes就找出对应的free list,将区块回收。
参考《STL源码分析》
谢谢阅读。