扩容机制

首先在VS2013底下,vector的扩容操作是每次扩容*1.5;在GCC环境下是2倍。

  • GCC下的扩容方式是以二倍形式扩容。
  • VS2013下是以1.5倍进行扩容

    所以可能会有疑问:
  • 问题一:为什么非要以倍数的形式增长,而不是以个数的形式增长。
  • 问题二:为什么每次增长是1.5倍或者2倍形式,而不是3倍或者4倍形式增长。

详解问题一

倍数方式空间拷贝数据次数

假设总共有n个元素,以m倍的形式增长。(比如现在举例n=100, m=2),所以,vector的push_back的操作次数可以是logmN,也就是log2(100),换算下来大概是需要进行7次扩容。这样的话,相当于旧空间数据到原空间数据的拷贝有7次。

个数方式空间拷贝数据次数

和倍数方式假设相同,n=100;这次m代表的是每次新空间的大小位n+m;m为新空间新增大小,比如这次m为10(每次新增10个空间)。所以这次的扩容次数为 100/10 = 10次,也就是说,插入100白个元素,需要扩容10次。
但是,如果n=1000的情况下, 以个数形式进行扩容就不能在为10了,否则拷贝空间次数将会太多
有的小伙伴要问:但是可以取100呀,想想,如果n=10的情况下,取100又不太合适,所以,以个数的形式来进行扩容显然不符合所用n的取值。
所以在STL中vector以倍数的形式进行扩容

详解问题二

如果以大于2倍的方式来进行扩容,下一次申请空间会大于之前申请所有空间的总和,这样会导致之前的空间不能再被重复利用,这样是很浪费空间的操作。所以,如果扩容一般基于(1, 2] 之间进行扩容

知乎上对于扩容机制的解释

  • 当m=2时
    因为每次扩容都满足等比数列通项公式an = a1*q^(n-1) = 4*2^(n-1)
    而前n-1项的内存和为Sn = a1*(1-q^(n-1))/(1-q) = 4*2^(n-1)-4
    所以第n项和前n-1和之间的差值为an - Sn = 4,这也就说明,前n-1项不能够完成第n项的空间重用。
  • 当m= 1.5时
    同样的方法,计算出 an - Sn = 8 - 4*1.5^(n-1)
    所以,当n达到一定的值的时候,就可以利用内存分配的方式将之前的空间进行重用,所以一般情况下为了使其为整数,选用2倍或者1.5倍来进行扩容。
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐