vector是一种容器,一种顺序容器,它的内存分配是连续的。与数组不同的是,数组的大小是静态的,不能动态的扩展,但是vector却可以。
vector的扩充机制:按照容器现在容量的一倍进行增长。vector容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续 的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空 间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。
STL - 内存分配 - 内存池
各种池子的作用在前面的文章讲过,本质上都是为了增加性能效率,内存池也一样,有的时候有很多频繁的小的内存申请和释放,如果没次都去向系统申请则会耗费很多时间,影响效率。因此需要内存池来过滤一些短小的内存操作。当然还有一个原因就是会引起内存碎片的问题。
STL的内存池的详细实现可以参考STL源码剖析当中的allocator一章。下面我们简单讲解下大致原理。
STL中的内存管理 当我们new一个对象时,实际做了两件事情:(1)使用malloc申请了一块内存。(2)执行构造函数。在SGI中,这两步独立出了两个函数:allocate申请内存,construct调用构造函数。这两个函数分别在<stl_alloc.h>和<stl_construct.h>中。
二、第一级配置器 第一级配置器以malloc(),free(),realloc()等C函数执行实际的内存配置、释放、重新配置等操作,并且能在内存需求不被满足的时候,调用一个指定的函数。
三、第二级配置器 在STL的第二级配置器中多了一些机制,避免太多小区块造成的内存碎片,小额区块带来的不仅是内存碎片,配置时还有额外的负担。区块越小,额外负担所占比例就越大。
如果要分配的区块大于128bytes,则移交给第一级配置器处理。 如果要分配的区块小于128bytes,则以
内存池管理(memory pool),又称之次层配置(sub-allocation):每次配置一大块内存,并维护对应的16个空闲链表(free-list)。下次若有相同大小的内存需求,则直接从free-list中取。如果有小额区块被释放,则由配置器回收到free-list中。
(1)空闲链表的设计 这里的16个空闲链表分别管理大小为8、16、24......120、128的数据块。这里空闲链表节点的设计十分巧妙,这里用了一个联合体既可以表示下一个空闲数据块(存在于空闲链表中)的地址,也可以表示已经被用户使用的数据块(不存在空闲链表中)的地址。

本文探讨了STL中的vector如何进行内存分配,尤其是其动态增长机制,以及STL内存池的概念和作用。当vector扩展时,它会重新申请内存并复制元素,导致原有迭代器失效。内存池通过预分配内存来提高小块内存申请和释放的效率,减少内存碎片。在STL中,内存管理分为两级配置器,对于小于128字节的内存请求,采用内存池策略,维护16个空闲链表进行管理。
1698

被折叠的 条评论
为什么被折叠?



