1.vector和string优先于动态分配的数组。
2.使用reserve来避免不必要的重新分配
关于stl容器会自动增长以便容纳下你放入其中的数据,只要没有超过它们的最大限制就可以。对于vector和string,增长过程是这样实现的:每当需要更多空间时,就调用与realloc类似的操作。这一类似于relloc的操作分为如下4部分:
(1)分配一块大小为当前容量的某个倍数的新内存。在大多数实现中,vector和string的容量每次以2的倍数增长,即每当容器需要扩张时,它们的容量即加倍。
(2)把容器的所有元素从旧的内存复制到新的内存中。
(3)析构掉旧内存中的元素
(4)释放旧内存
reserve成员函数能使你把重新分配的次数减少到最低限度,从而避免了重新分配和指针迭代器引用失效带来的开销。
简单概括一下四个相互关联、但有时会被混淆的成员函数。在标准容器中,只有vector和string提供了所有这四个函数:
(1)size() 告诉你容器中有多少个元素,它不会告诉你该容器为自己所包含的元素分配了多少内存。
(2)capacity()告诉你容器利用已经分配的内存可以容纳多少元素。这是容器所能容纳的元素总数,而不是它还能容纳多少个元素。如果你想知道一个vector有多少未被使用的内存,就得从capacity()中减去size()。如果size和capacity返回同样的值,就说明容器中不再有剩余空间了,因此下一个插入操作(push_back)将导致上面所提到的重新分配过程。
(3)resize(xx)强迫容器改变到包含n个元素的状态。在调用resize之后,size将返回n。如果n比当前的大小(size)要小,则容器尾部的元素将会被析构掉。如果n比当前的大小要大,则通过默认构造函数创建的新元素将被添加到容器的末尾。如果n比当前的容量要大,那么在添加元素之前,将先重新分配内存。
(4)reserve(xx)强迫容器把它的容量变为至少是n,前提是n不小于当前的大小。这通常会导致重新分配,因为容量需要增加。(如果n比当前的容量小,则vector什么也不做)
因此,避免重新分配的关键在于,尽早的只用reserve,把容器的容量设为足够大的值,最好是在容器刚被构造出来之后就使用reserve。
3.注意string实现的多样性
4.了解如何把vector和string数据传给旧的API
5.使用“swap技巧”除去多余的容量。
6.避免使用vector<bool>
vector<bool>不是一个stl容器,也不存储bool。在一个典型的实现中,储存在vector中的每个bool仅占一个二进制位,一个8位的字节可容纳8g个“bool”。在内部vector<bool>使用了与位域一样的思想,来表示它所存储的那些bool;实际上只是假装存储了这些bool。
vector<bool>不完全满足STL容器的要求;你最好不要使用它;你可以使用deque<bool>和bitset来替代它,这两个数据结构几乎能做vector<bool>所能做的一切事情。