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

本文深入探讨了C++标准库中的vector和string如何管理内存,特别是在需要扩容时的realloc等价操作。详细介绍了扩容过程的四步:分配新内存、元素拷贝、销毁旧对象和回收内存,以及如何使用reserve函数避免不必要的重新分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

对于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. 保留可能需要的最大空间,然后,添加数据完成,修掉多余的容量

 

转载于:https://www.cnblogs.com/kidycharon/p/10009694.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值