1.基本组件
容器(Container)、算法(Algorithm)、迭代器(Iterator)、仿函数(Functor)、容器适配器(Adapter)、空间配置器(Allocator)
2.组件关系容器通过空间配置器获取数据存储空间;算法通过迭代器存取容器内容;
仿函数帮助算法完成不同策略的选择;容器适配器可以修饰或套接仿函数;
二、空间配置器
#include<memory>//头文件
#include<stl_alloc.h>//负责内存空间的配置与释放
#include<stl_construct.h>//负责对象内容的构造与析构
1.对象的构造与析构
1)由定义的全局函数construct()和destory()来进行;
2)其中destory中用到了Traits技术,通过判断类的类别进行不同的析构操作,
类的析构函数为trivial(无用的)则无视、类的析构函数为no-trivial(需要释放内存等必要操作)则执行,
通过这种方式可以提高效率。
2.内存空间的申请与释放采用双层配置器
1)一级配置器(申请内存大于128byte)
a. allocate():直接使用malloc从系统的heap空间申请内存,若内存不足调用oom_malloc();
b. deallocate():直接使用free(p)释放内存;
c. oom_**alloc():(out of memory)实现了类似C++ new-handler机制,即在内存分配不够的情况下,先执行客户指定的处理
例程(不断尝试释放内存并重新配置),若内存失败则丢出bad_alloc异常。
注意:设计和设定内存不足处理例程是客户端的责任。
2)二级配置器(申请内存小于等于128byte)
a. allocate(): 首先判断申请的内存大小,超过128byte调用第一级配置器,否则启动第二级配置器从一个预先分配好的
内存池中取内存交付给用户。这个内存池由16个负责不同大小(8-128byte)区块的自由链表组成类似于
hash桶结构,配置器会根据申请的内存大小(round up成8的倍数)从对应的自由链表块取表头给
客户。表头存储了对应内存池中的地址。如果要申请的大小在空闲链表上没有,就从内存池中获取 (chunk_alloc),若内存池空间不够就通过malloc扩充内存池空间(大小为需求量的两倍还有随着申请次数
增加而愈来愈大的附加量)。若从系统heap空间申请内存失败,就先从自由链表中寻找尚未使用且区块够大的内 存,若没有就调用第一级配置器(通过oom能否获得内存)。
b. deallocate():首先判断释放的内存大小,超过128byte调用第一级配置器,否则启动第二级配置器根据内存大小找到对应的自由链表块,将其加入表头。
3)采用两级配置器的优点:小内存的快速分配与释放;避免了内存碎片的产生;尽可能最大化内存利用率;
3.内存基本处理工具
1)uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result):
将迭代器first到last内的数据copy到result。
2)uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x):
用x初始化迭代器从first到last的范围。
3)uninitialized_fill_n(ForwardIterator first, Size n ,const T& x):
为指定范围内的所有元素设定相同的初值。