您的位置:首页 > 其它

【面经笔记】STL

2017-07-16 21:10 120 查看

空间配置器:

为什么不说allocator是内存配置器:空间不一定是内存,空间也可以是磁盘或其他存储介质,你可以写一个allocator直接向硬盘取空间。

SGI STL的配置器名为alloc,是缺省的空间配置器。

虽然也定义了一个符合部分标准的allocator配置器,但只是把C++中new和delete简单包装而已,性能不佳。

SGI std::alloc:

new包含了:operator new内存配置 和 对象构造 两个过程。

delete包含了: 对象析构 和 operator delete内存释放

STL 将两个阶段操作区分开来:

内存配置由alloc::allocatr()负责,内存释放由alloc::deallocate()负责;

对象构造由construct()负责,对象析构由deallocate()负责。

考虑小型区块造成的内存破碎问题,SGI设计了双层级配置器

第一级直接使用allocate()调用malloc()、deallocate()调用free(),使用类似new_handler机制解决内存不足,配置无法满足的问题。

第二级视情况使用不同的策略,当配置区块大于128bytes时,调用第一级配置器,当配置区块小于128bytes时,采用内存池的整理方式:配置器维护16个(128/8)自由链表,负责16种小型区块的此配置能力。内存池以malloc配置而得,如果内存不足转第一级配置器处理。

[b]内存池[/b]

内存池管理:每次配置一大块内存,并维护对应之自由链表:free_list,下次若还有相同大小的内存需求,直接从链表中拔出,如果客户端释还小额区块,就由配置器回收到free_list中。为了方便管理,任何小额内存需求均上调至8的倍数。

allocator需要维护一个存储16个空闲块列表表头的数组free_list,数组元素i是一个指向块大小为8*(i+1)字节的空闲块列表的表头,一个指向内存池起始地址的指针start_free和一个指向结束地址的指针end_free。空闲块列表节点的结构如下:

union obj
{
union obj *free_list_link;
char client_data[1];
};


这个结构可以看做是从一个内存块中抠出4个字节大小来,当这个内存块空闲时,它存储了下个空闲块,当这个内存块交付给用户时,它存储的时用户的数据

当free_list不够时,从内存池中取新空间为free_list填充新空间。

当内存池不够时,从堆申请新空间。

当堆不够时,交由第一级配置器使用类似new_handler机制处理。

iterator

traits(萃取)技术:

利用模板的参数推导机制,获取任意迭代器的特征信息:

Template<class T>
Struct  iterator_traits
{
Typedef  typename T::value_type  value_type;
}
如果T定义有自己的value_type,通过traits的作用,萃取出来的就是T::value_type。


这种多了一层间接性好处是可以拥有原生指针的偏特例化版本:如偏特例化原始指针版本
iterator_traits<T*>和iterator_traits<const T*>


原生指针int*虽不是一种类类型,亦可通过iterator_traits取其value_type。

序列容器:vector

频繁对vector调用push_back()对性能的影响和原因:

push_back()将新元素插入vector尾端时,首先检查是否还有备用空间,如果容量被用完,并不是在原空间后接续新空间,而是以原大小的两倍重新分配一块空间,将原内容拷贝过来,并添加上新元素,释放原空间。

一旦push_back()引起空间重新配置,指向原vector的所有迭代器失效。

序列容器:list

双向链表

STL list是一个环状双向链表

序列容器:deque 双向队列

deque没有容量(capacity)的概念,动态的以分断连续空间组合而成,可以随时增加一段新的空间并链接起来。

deque是由一段一段的连续空间构成,由迭代器维护整体连续的假象

中控器为一个连续数组空间(映射/map),每个元素都是指针,指向一段连续线性空间(缓冲区),缓冲区大小一致

在deque上排序很慢,可将数据拷贝至vector ,排序后拷贝回deque

容器适配器:stack 栈

stack底层默认以deque实现,不提供迭代器

stack<int,deque<int>>
stack<int,list<int>>


容器适配器:queue 队列

queue底层默认是deque实现,不提供迭代器

queue<int,deque<int>>
queue<int,list<int>>


heap只有算法,属于幕后工作者,是优先队列的助手

容器适配器:priority queue 优先队列

优先队列默认是最大堆实现

最大堆默认是vector实现的完全二叉树:

http://blog.csdn.net/xiaxzhou/article/details/74943175

priority_queue<int,vector<int>,less<int>>
priority_queue<int,vector<int>,greater<int>>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: