Effective_STL 学习笔记(十四) 使用 reserve 来避免没必要的重新分配

对于vector和string,当需要更多的空间,以realloc等价的思想来增长。类似于realloc的操作有四个部分:

  1. 分配新的内存块,它有容器目前容量的几倍。大部分实现中,vector和string的容量以2为因数增长。

   也就是说,当容器必须扩展时,它的容量每次翻倍。

  2. 把所有元素从容器的旧内存拷贝到它的新内存。

  3. 销毁旧内存中的对象。

  4. 回收旧内存。

这些步骤都是很昂贵的,而且所有指向 vector 和 string 中的迭代器、指针和引用都会失效。

在标准容器中,只有 vector 和 string 提供了所有这四个相关的成员函数:

  1. size() 告诉你容器中多少个元素;

  2. capacity() 告诉你容器在它已经分配的内存中可以容纳多少元素;

  3. resize( Container::size_type n ) 强制把容器改为容纳 n 个元素。

  4. reserve( Container::size_type n ) 强制容器把它的容量改为至少 n,提供 n 不小于当前大小 

以上,只要有元素插入而且容器的容量不足时就会发生重新分配(包括它们维护的原始内存分配和回收,对象的拷贝和析构和迭代器、指针和引用的失效)。所以避免重新分配的关键是使用 reserve 尽快把容器的内容设置为足够大,最好在容器被构造之后立刻进行。

1   vector<int> v;
2   v.reserve(1000);
3   for( int i = 1; i <= 1000; i++ )
4     v.push_back(i);

这样循环中不会重新分配。

在大小和容量的关系让我们可以预言什么时候插入将引起 vector 或 string 执行重新分配

1   string s;
2   . . .
3   if( s.size() < s.capacity() )
4     s.push_back( 'x' );

回顾本条款的主旨,通常两种情况使用 reserve 来避免不必要的重新分配:

  1. 确切或者大约知道有多少元素最后出现在容器中。

  2. 保留可能需要的最大空间,然后,添加数据完成,修掉多余的容量

猜你喜欢

转载自www.cnblogs.com/kidycharon/p/10009694.html