现在的位置: 首页 > 综合 > 正文

【STL】Alloc细节

2018年04月23日 ⁄ 综合 ⁄ 共 1591字 ⁄ 字号 评论关闭

一、实现

1、为了精密分工,STL allocator将两阶段操作分开,内存配置操作由alloc::allocate()负责,内存释放操作由alloc::deallocate()负责

对象构造操作由::construct()负责,对象析构操作由::destroy()负责

2、对象构造前的空间配置和对象析构后的空间释放,由<stl_alloc.h>负责,SGI对此的设计哲学如下:

向system heap要求空间

考虑多线程状态

考虑内存不足时的应变措施

考虑过多“小型区块”可能造成的内存碎片问题

3、考虑到小型区块所可能造成的内存破碎问题,SGI设计了双层级配置器,第一级直接使用malloc和free,第二级视情况采用不同策略。

4、第一级配置器以malloc、free、realloc等C函数执行实际的内存配置、释放、重配置等操作,并实现出类似C++ new-handler的机制

,它不能直接运用C++ new-handler的机制,因为它并非使用::operator new来配置内存。

5、所有C++ new-handler的机制是:你可以要求系统在内存配置需求无法被满足时,调用一个你所指定的函数。

换句话说,一旦::operator new无法完成任务,在丢出std::bad_alloc异常状态之前,会先调用由客户端指定的处理例程,该处理

例程通常即被称为new-handler。

6、SGI第二级配置器的做法:如果区块够大,超过128bytes时,就移交第一级配置器处理,当区块小于128bytes时,则以内存池管理,

此法又称为次层配置:每次配置一大块内存,并维护对应之自由链表,下次若再有相同大小的内存需求,就直接从自由链表中拨出,

如果释放小额区块,就由配置器回收到自由链表中。

7、SGI第二级配置器会主动将任何小额区块的内存需求量上调至8的倍数,并维护16个free-lists,各自管理大小分别为8,16,32,,,128的

小额区块。

8、索求任何一块内存,都得有一些“税”要交给系统。

 

二、内存基本处理工具

1、STL定义了5个全局函数,作用于未初始化空间上。

construct

destroy

uninitialized_copy 对应于高层次函数 copy

uninitialized_fill 对应于高层次函数 fill

uninitialized_fill_n 对应于高层次函数 fill_n

2、copy作用

uninitialized_copy使我们能够将内存的配置与对象的构造行为分离开来。

如果你需要实现一个容器,uninitialized_copy这样的函数会为你带来很大的帮助,因为容器的全区间构造函数通常以两个步骤完成:

配置内存区块,足以包含范围内的所有元素

使用uninitialized_copy,在该内存区块上构造元素。

 

C++标准规格书要求uninitialized_copy具有“commit or rollback”语意,意思是要么“构造出所有必要元素”,要么“不构造

任何东西”。

3、fill作用

uninitialized_fill也使我们能够将内存的配置与对象的构造行为分离开来。

3、fill_n作用

uninitialized_fill_n也使我们能够将内存的配置与对象的构造行为分离开来。

 

三、相关术语

1、POD

意思是 Plain Old Data,也就是标量型别或传统的C struct型别。POD型别必然拥有 trivial ctor/dtor/copy/assignment函数。

四、总结

空间配置器总是隐藏在一切组件的背后,默默工作,默默付出。

因为整个STL的操作对象都存放在容器之内,而容器一定需要配置空间以置放资料。

为什么不说allocator是内存配置器而说是空间配置器呢?

因为空间不一定是内存,空间也可以使磁盘或其他辅助存储介质。

是滴,你可以写一个allocator,直接向硬盘取空间。

 

抱歉!评论已关闭.