本文重点在于介绍读STL过程中,要注意的知识点。不在于如何使用STL。
vector
- vector是动态增加大小,当已有空间长度无法满足新的插入时的处理方式并不仅仅是简单的直接二倍增长。
如果数据插入后的总长度 < 当前空间长度的两倍,则直接申请一块原大小两倍的空间;如果数据插入后的总长度 >
当前空间长度的两倍,则申请总长度大小的空间。然后将原空间的元素拷贝到新的空间,并释放掉。
//摘录的stl,大小调整源码
const size_type len = old_size + max(old_size,n);
对vector的任何操作,一旦引起空间重新配置,指向原vector的所有的迭代器就都失效了。
正确释放vector内存
当vector、string大量插入数据后,即使删除了大量数据(或者全部都删除,即clear) 并没有改变容器的容量(capacity),所以仍然会占用着内存。 为了避免这种情况,我们应该想办法改变容器的容量使之尽可能小的符合当前 数据所需(shrink to fit)
vector<type> v;
//.... 这里添加许多元素给v
//.... 这里删除v中的许多元素
vector<type>(v).swap(v);
//此时v的容量已经尽可能的符合其当前包含的元素数量
//对于string则可能像下面这样
string(s).swap(s);
上面代码,先创建一个临时拷贝与原先的vector一致,紧接着将该拷贝与原先的vector v进行交换。此时,执行交换后,临时变量会被销毁,内存得到释放。此时的v即为原先 的临时拷贝,而交换后的临时拷贝则为容量非常大的vector(不过已经被销毁),当然,上面这种方法虽然释放了内存,但是同时也增加了拷贝数据的时间消耗。 不过一般需要重新调整容量的情况都是 vector本身元素较少的情况,所以 时间消耗可以忽略不计。
- clear、erase只是简单地将元素移动,调整finish的位置,并没有引起空间变化,也没有destroy掉元素。
- pop_back,将元素移出,并destroy了。
对于STL中的向量容器vector是一个非常高效的实现,但是在webkit中的WTF模块中,它里面的vector是直接放弃了STL的vector,它是利用google的tcmalloc来管理内存的,比stl的高效。
通常情况下,Tcmalloc的内存管理效率比glibc高。像Ngnix和MySQL中就借助tcmalloc来管理和优化内存。