std::vector::reserve 函数在 C++ 中用于预分配内存,避免在元素增加时多次重新分配内存,从而提高性能。

它最常用于需要频繁向 vector 中添加元素,并且可以预估容器的最终大小的场景。

作用

reserve 函数的主要作用是:

  1. 预分配容量:它提前为 vector 分配一定数量的内存(但不会改变当前 vector 的元素数量 size)。也就是说,它只是增加 vector 的容量 capacity,使其能够容纳更多元素,而不需要反复分配和释放内存。

  2. 避免多次内存分配和拷贝:在 vector 中,如果你频繁调用 push_back 向容器添加新元素,而没有事先为 vector 分配足够的容量,容器在容量不足时会自动扩容。这会导致每次扩容时进行内存分配,并将现有元素拷贝到新的内存地址。reserve 通过提前分配足够的空间,减少或避免了这些昂贵的操作。

场景

reserve 通常用于以下场景:

  1. 已知或可以预估元素的数量:如果你知道或者可以大致估计 vector 最终会存储多少个元素,可以使用 reserve 来一次性分配足够的内存空间,避免扩容时频繁的内存分配与拷贝。

    示例:

    #include <iostream>
    #include <vector> int main() {
    std::vector<int> vec;
    vec.reserve(100); // 预先分配100个元素的空间 for (int i = 0; i < 100; ++i) {
    vec.push_back(i); // 不会触发多次扩容
    } std::cout << "Vector size: " << vec.size() << std::endl;
    std::cout << "Vector capacity: " << vec.capacity() << std::endl; return 0;
    }

    在这个例子中,调用 reserve(100) 会一次性分配能够容纳 100 个元素的内存空间。因此,在 push_back 添加元素时,不会频繁地重新分配内存,提升了性能。

  2. 性能优化在高性能的应用中,特别是需要处理大量数据时,如果向 vector 中添加元素的操作非常频繁且每次添加元素都会导致 vector 扩容,会严重影响性能。reserve 可以通过减少内存分配和拷贝操作来提升性能。

  3. 避免扩容导致的迭代器失效vector 扩容时,之前的元素会被拷贝到新的内存地址,导致之前的迭代器失效。如果提前使用 reserve 分配好足够的空间,可以避免这种问题,特别是在对迭代器的连续访问中。

    迭代器失效示例:

    #include <iostream>
    #include <vector> int main() {
    std::vector<int> vec;
    vec.reserve(10); // 预留空间避免迭代器失效 vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3); // 获取迭代器
    auto it = vec.begin(); // 继续向vector添加元素
    vec.push_back(4); // 不会导致迭代器失效 std::cout << "First element: " << *it << std::endl; // 输出正确结果 return 0;
    }

reserveresize 的区别

  • reserve:只改变 vector容量,但不改变其大小。也就是说,它只预分配内存,但并不实际增加或减少 vector 中的元素。
  • resize:不仅改变 vector大小,还会相应地创建或销毁元素。它会让 vector 的大小变为指定的大小,添加默认构造的元素(如果扩大),或删除多余的元素(如果缩小)。

示例:

std::vector<int> vec;
vec.reserve(10); // 仅分配内存,但不添加元素,vec.size() 仍为 0 vec.resize(10); // 改变size,vec.size() 为 10,默认值填充

总结

std::vector::reserve 在以下场景非常有用:

  • 需要大量动态添加元素时。
  • 知道或能够预估元素的数量时。
  • 想要避免不必要的内存分配、拷贝和迭代器失效时。

通过合理使用 reserve,可以有效地优化程序的性能,减少 vector 的内存管理开销。

std::vector::reserve的更多相关文章

  1. c++转载系列 std::vector模板库用法介绍

    来源:http://blog.csdn.net/phoebin/article/details/3864590 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作 ...

  2. C++ 中的std::vector介绍(转)

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...

  3. std::vector介绍

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...

  4. 使用std::vector优化点云动画显示一例

    1. 准备 使用std::vector应该知道几点: (1)内存连续的容器,有点像数组 (2)与std::list相比,插入和删除元素比较慢- 因为数据迁移 (3)添加元素可能会引发内存分配和数据迁移 ...

  5. std::vector利用swap()函数进行内存的释放【转】

    首先,vector与deque不同,其内存占用空间只会增长,不会减小.比如你首先分配了10,000个字节,然后erase掉后面9,999个,则虽然有效元素只有一个,但是内存占用仍为10,000个.所有 ...

  6. C++ std::vector

    std::vector template < class T, class Alloc = allocator<T> > class vector; // generic te ...

  7. 编程杂谈——std::vector与List<T>的性能比较

    昨天在比较完C++中std::vector的两个方法的性能差异并留下记录后--编程杂谈--使用emplace_back取代push_back,今日尝试在C#中测试对应功能的性能. C#中对应std:: ...

  8. C++ std::vector 基本用法2

    #include <iostream> #include <vector> using namespace std; int main() { int ar[10] = { 1 ...

  9. C++ std::vector指定位置插入

    使用vector,必须加上:#include <vector> 1.初始化vector,一般有这几种方式: std::vector<std::wstring> v1; //创建 ...

  10. C++ folly库解读(二) small_vector —— 小数据集下的std::vector替代方案

    介绍 使用场景 为什么不是std::array 其他用法 其他类似库 Benchmark 代码关注点 主要类 small_vector small_vector_base 数据结构 InlineSto ...

随机推荐

  1. 在Django REST framework (DRF) 中,`request.query_params` 和 `request.data` 区别

    在Django REST framework (DRF) 中,request.query_params 和 request.data 都是用来获取请求中的数据,但是它们之间有一些关键的区别: requ ...

  2. 手把手教你集成GraphRag.Net:打造智能图谱搜索系统

    在人工智能和大数据发展的背景下,我们常常需要在项目中实现知识图谱的应用,以便快速.准确地检索和使用信息. 今天,我将向大家详细介绍如何在一个新的.NET项目中集成GraphRag.Net,这是一个参考 ...

  3. ansible 部署hadoop

    规划 ansible 节点 ansible controller 镜像rhel 8.2 镜像ansible hadoop 集群 master slave1 slave2 镜像centos 1810 0 ...

  4. Python和RPA网页自动化-处理iframe嵌入式框架

    以网易云为例,歌曲列表都在<iframe>框架下,使用Python和RPA网页自动化依次点击10首歌的播放键 1.python代码 从网页源代码可见,整个歌曲列表都在<iframe& ...

  5. Python和RPA网页自动化-发送邮件

    以163邮箱为例,分别使用Python和RPA网页自动化发送邮件到指定邮箱 其中2个方法都需要用到163邮箱授权码,开启IMAP/SMTP服务即可得到授权码(POP3/SMTP服务不用开启) 1.py ...

  6. Jmeter函数助手13-threadGroupName

    threadGroupName函数获取当前线程组的名称.该函数没有参数,直接引用即可. 1. 返回当前线程组的名称

  7. 低代码如何借助 K8s 实现高并发支持?

    引言 在当今这个数字化时代,互联网的普及和技术的飞速发展使得应用程序面临着前所未有的挑战,其中最为显著的就是高并发访问的需求.随着用户数量的激增和业务规模的扩大,如何确保应用在高并发场景下依然能够稳定 ...

  8. 【Scala】01 基础了解

    Features 特性 1.基于JVM,完全兼容Java 2.同样具有跨平台,可移植,垃圾回收 3.比Java更加的面向对象[完全面向对象] 4.函数式编程 5.面向大数据处理,对集合容器框架有一定的 ...

  9. 【Win10】找不到Telnet命令

    百度才发现原来我的Telnet程序就没启动... CMD终端就找不到命令... 但是有一点要注意!不能使用CMD之外的终端访问[GitBash访问无效] 打开控制面板,点卸载程序: 然后点击启动和关闭 ...

  10. 【转载】 5:0!AI战胜人类教官,AlphaDogfight大赛落幕

    原文:https://baijiahao.baidu.com/s?id=1675621109599102721&wfr=spider&for=pc ------------------ ...