STL源码解析-02配置器-02stl解析
*************************************************
* STL中,将内存的申请与对象的构造分开进行,分别进行定义,具体来说,包含在两个文件中,<stl_construct.h>和<stl_alloc.h>。
*
* stl_construct.h:
* construct:采用了placement new操作符。
* destroy:一个泛化模板的实现,根据__type_traits中的has_trivial_destructor是__true_type还是__false_type,分别调用相应的偏特化版本。
* 一个对char *的特化实现。
* 一个对wchar_t*的特化实现。
* 一个对T*的特化实现。
*
* stl_alloc.h:
* 在STL中,考虑到小型区域可能造成的内存破碎问题,SGI设计了双层级配置器;
* 第一级:__malloc_alloc_template,直接使用malloc()和free()。
* 第二级:__default_alloc_template,如果配置区超过128bytes,调用第一级;如果小于,采用复杂的内存池进行。
*
* 第一级的基本设计思想:
* allocate:通过malloc进行内存分配,失败调用内部函数oom_allocate,在oom中不断的尝试释放、配置,如果指定了malloc_handler函数,执行该函数。
* deallocate:直接调用free。
* reallocate:调用realloc函数,分配失败时,与malloc的处理方式一样。
*
* 第二级的基本思想:
* __default_alloc_template中维护着16个free-list,每个list管理的大小分别为:8,16,32,...,120,128,所以最后分配的都是8的倍数。
* allocate:若n大于128byte,调用第一级;
* 小于,找到round_up(向上对齐,是8的倍数)之后对应的list,如果list有节点,返回;
* 如果没有,调用refill函数,从内存池中分配20个n大小的内存空间,将20这个大小挂在对应的list之下。
* chunck_alloc:在refill中被调用,该函数是在内存池中分配空间给相应的list,实现的过程比较复杂。如果内存池的容量大于请求大小(n*size),直接分配;
* 如果小于请求大小但是可以分配至少一个的空间,则返回最大能分配的内存地址;
* 如果连一个的大小都不够,将内存池的空间挂到相应的list之下,重新申请空间,大小为原来的2倍+附件量,如申请空间成功,递归调用自己;
* 如果失败,从size对应的list开始往后找,看其他LIST中有没有空间可以分配,若没有满足的,调用第一级的试一试,如果不行,第一级会抛异常。
************************************************************
***********************************************************
* 内存基本处理工具
* uninitialized_copy(InputIterator first, InputIterator last, ForeardIterator result):使用copy构造函数,将[first,last)范围内的每一个对象产生
* 一个复制品,放进输出的范围。
* uninitialized_fill(InputIteraot first, InputIterator last, const T&):对[first,last)范围内的每一个迭代器调用构造函数。
* uninitialized_fill_n(InputIteraot first, Size n, const T&x):对[first,first+n)范围内的每一个迭代器调用构造函数。
* **********************************************************
************************************************************
*
* Traits变成技法:
* 在STL中,很多地方都用到了traits编程方式,他和模板的偏特化结合起来一起用,在迭代器,普通类型中都有traits的应用。
* struct __true_type {};
* struct __false_type {};
*
* template <class T>
* struct __type_traits{
* typedef __false_type has_trivial_default_constructor;
* typedef __false_type has_trivial_copy_constructor;
* typedef __false_type has_trivial_assignment_operator;
* typedef __false_type has_trivial_destructor;
* typedef __false_type is_POD_type; //POD:Plain Old Type,传统的C struct,必然拥有ctor/dtor/copy/assignment。
* }
*
* 对于具体的int,long,double等类型可以特化实现该traits,定义与之相对应的typedef。
* trait其实是对类型的一种说明,通过类型的某些属性,我们可以针对性的偏特化模板。
* 如:
* template <class ForwardIterator, class T>
* inline void uninitialized_fill(ForwardIterator first, ForwardItertor last, const T& x)
* {
* __uninitialized_fill(first, last, x, value_type(x));
* }
*
* template <class ForwardIterator, class T, class T1>
* inline void __uninitialized_fill(ForwardIterator first, ForwardItertor last, const T& x, T1*)
* {
* typedef typename __type_traits<T1>::is_POD_type is_POD;
* __uninitialized_fill_aux(first, last, x, is_POD);
* }
* //进行函数的偏特化
* template <class ForwardIterator, class T>
* inline void __uninitialized_fill_aux(ForwardIterator first, ForwardItertor last, const T& x, __true_type)
* {
* fill(first,last,x);
* }
*
* template <class ForwardIterator, class T>
* inline void __uninitialized_fill_aux(ForwardIterator first, ForwardItertor last, const T& x, __false_type)
* {
* //
* }
* 偏特化看中的是类型的不同,如果把__false_type和__true_type分别定义为ture和false的话,就没法应用函数的偏特化。
*****************************************************************************************
浙公网安备 33010602011771号