STL源码剖析读书笔记3

SGI空间配置器

SGI STL的每一容器都已经指定其缺省的空间配置器为alloc。例如:
vector的声明:
template<class T,class Alloc = alloc> //缺省
class vector {...};

我们所习惯的new/delete内存配置:

class Foo{...};
Foo* pf = new Foo; //配置内存然后分配对象
delete pf;//将对象析构然后释放
这其中包含两个阶段,调用::operator new配置内存,Foo::Foo()构造对象

为了精密分工,STL allocator决定将这俩个阶段操作分开来,alloc::allocate()/alloc::deallocate()/:construct()/:destory()/。并将配置器定义与memory头文件内。

construct

上述construct()接受一个指针p和一个value,该函数的用途就是将初值设定到指定的空间上去,用C++中的placement new来完成。

destroy

两个版本,第一个版本接受一个指针,然后将该指针指向之物析构掉。第二个版本接受范围的迭代器,将[first,last)范围内的所有对象全部析构掉,这里先用value_type()获得迭代器所指对象的类别,再用type_traits《T》判断该类别的析构函数是否无关痛痒。

当operator new申请一个内存失败的时候,它会进行如下的处理步骤:
1、如果存在客户指定的处理函数,则调用处理函数(new_handler),如果不存在则抛出一个异常。
2、继续申请内存分配请求。
3、判断申请内存是否成功,如果成功则返回内存指针,如果失败转向处理步骤1
一个设计良好的new_handler必须做以下事情:
1、删除其它无用的内存,使系统具有可以更多的内存可以使用,为下一步的内存申请作准备。
实现此策略的办法是:程序一开始执行就分配一大块内存,当new_handler被调用时,将它们释放还给程序使用。
2、设置另外一个new_handler。
如果当前的new_handler不能够做到更多的内存申请操作,或者它知道另外一个new_handler可以做到,则可以调用set_new_handler函数设置另外一个new_handler,这样在operator new下一次调用的时候,可以使用这个新的new_handler。
3、卸载new_handler,使operator new在下一次调用的时候,因为new_handler为空抛出内存申请异常。
4、new_handler抛出自定义的异常
5、不再返回,调用abort或者exit退出程序

第一级配置器源码剖析


你可能感兴趣的:(读书笔记,STL)