规定
string和vector实现一样。
为了支持快速随机访问,vector中对象在内存中必须是连续存储的。
问题1
但是vector又是可变大小的。所以当vector空间用完了的时候,我们不能将元素添加到其他位置,因为vector必须连续存储才能保证快速随机访问。
解决1
所以vector策略是:开辟新的更大的连续空间,将vector中原来的元素移动到新空间,然后释放旧空间。
问题2
但是有出现问题:如果我们每添加一个元素,就做一次这样的移动数据到新内存操作,又释放旧内存,这样操作太频繁,并且性能肯定非常差。
解决2
所以标准库使用能够减少空间分配次数的策略——预先分配策略。
vector会先分配一个比需求更大的空间,作为预留。
vector有几个属性
v.size()表示当前已有元素数量
v.capacity() 表示vector实际总容量,因为有预留空间
v.reserver(n) 表示要求vector的容量是多少。如果大于capacity则vector扩容,如果小于capacity则不需要扩容。
举个例子:比如我每次给vector添加一个元素,当添加了24个元素时,size为24,这时capacity为32.这个capacity大小为标准库的实现策略来决定的。
也就是只要我们添加操作不超出capacity,我们的vector就不会频繁扩容,尽量减小对性能的影响。
每个vector都实现自己的内存分配策略,但是必须遵循一条就是:只有迫不得已的时候才分配新的空间。
再举个例子:当size大小为50时,这时capacity也是50。这时我们再增加一个元素,发现size为51,而capacity变为100.也就是这个策略是将原容量翻倍了。
总结
vector实现策略:
- vector可以扩容,开辟新的更大的连续空间,将vector中原来的元素移动到新空间,然后释放旧空间(保证元素在内存中连续)
- vector有个capacity作为预留容量,只有元素数量需求超过capacity的时候才对vector进行扩容,具体扩容策略由标准库决定:比如可以使用翻倍扩容。(目的是减少扩容次数,减少性能影响)。