news 2026/4/15 12:09:19

【std::vector】size、capacity小结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【std::vector】size、capacity小结

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

      • 一、核心比喻(快速理解)
      • 二、正式定义与特点
        • 1. size(大小)
        • 2. capacity(容量)
      • 三、实例演示(直观看到变化)
      • 四、关键机制:vector的扩容原理
      • 五、易混淆的`resize`和`reserve`(结合size/capacity)
      • 六、总结关键点

在C++的vector中,size(大小)capacity(容量)是两个核心概念,对应vector底层动态数组的元素数量内存空间上限,理解它们的区别和联系是高效使用vector的关键。下面用通俗比喻+定义+实例+内存机制的方式详细讲解。

一、核心比喻(快速理解)

vector想象成一个装小球的纸箱

  • size:纸箱里实际装的小球数量(能直接数到的小球个数)。
  • capacity:纸箱最大能容纳的小球数量(不换更大的纸箱时,最多能装这么多)。
  • 当小球数量(size)超过纸箱容量(capacity)时,你需要换一个更大的纸箱(扩容),把原来的小球全部搬过去,这个过程会消耗额外的时间和资源。

二、正式定义与特点

1. size(大小)
  • 定义vector实际存储的元素个数
  • 获取方式:调用vector的成员函数size()
  • 合法访问范围:可以通过下标[0, size()-1]访问元素(超出这个范围是未定义行为,除非用at()会抛异常)。
  • 影响size的操作:所有会增加/删除元素的操作都会改变size,比如:
    • 构造函数(vector<int> arr(5)size=5)。
    • push_back()(尾部加元素,size+1)、pop_back()(尾部删元素,size-1)。
    • resize(n)(直接设置sizen)。
    • insert()(插入元素,size增加)、erase()(删除元素,size减少)。
2. capacity(容量)
  • 定义vector当前分配的连续内存空间能容纳的最大元素个数(无需扩容时的上限)。
  • 获取方式:调用vector的成员函数capacity()
  • 核心特点capacity ≥ size(永远成立,因为内存至少要装下当前所有元素)。
  • 影响capacity的操作:只有内存重新分配的操作才会改变capacity,比如:
    • reserve(n)(手动预留容量,若n>原capacity,则capacity变为n;否则无变化)。
    • 扩容(当push_back()/insert()导致size超过capacity时,vector会自动分配更大的内存,capacity随之增大)。
    • shrink_to_fit()(C++11+,尝试将capacity缩小到与size相等,注意:这是请求而非强制,编译器可能忽略)。
    • 注意:pop_back()/erase()只会减少size不会改变capacity(内存不会自动释放,避免频繁的内存分配/释放)。

三、实例演示(直观看到变化)

通过代码一步步看sizecapacity的变化,以GCC编译器(扩容策略为原容量的1.5倍)为例(MSVC是2倍,规律一致)。

#include<vector>#include<iostream>usingnamespacestd;intmain(){// 1. 空vector:size=0,capacity=0(无元素,无内存)vector<int>arr;cout<<"空vector:size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=0,capacity=0// 2. push_back第一个元素:size=1,capacity=1(自动分配内存)arr.push_back(1);cout<<"push_back(1):size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=1,capacity=1// 3. push_back第二个元素:size=2,capacity=2(扩容到2,1*2=2)arr.push_back(2);cout<<"push_back(2):size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=2,capacity=2// 4. push_back第三个元素:size=3,capacity=3(GCC扩容到1.5倍:2*1.5=3)arr.push_back(3);cout<<"push_back(3):size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=3,capacity=3// 5. reserve(10):手动预留容量,size不变,capacity=10arr.reserve(10);cout<<"reserve(10):size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=3,capacity=10// 6. push_back(4):size=4,capacity仍为10(容量足够,无需扩容)arr.push_back(4);cout<<"push_back(4):size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=4,capacity=10// 7. pop_back():size=3,capacity仍为10(只删元素,不释放内存)arr.pop_back();cout<<"pop_back():size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=3,capacity=10// 8. resize(5):size=5(补充2个默认值0),capacity仍为10arr.resize(5);cout<<"resize(5):size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=5,capacity=10// 9. shrink_to_fit():尝试将capacity缩小到size=5arr.shrink_to_fit();cout<<"shrink_to_fit():size="<<arr.size()<<",capacity="<<arr.capacity()<<endl;// size=5,capacity=5return0;}

输出结果(GCC)

空vector:size=0,capacity=0 push_back(1):size=1,capacity=1 push_back(2):size=2,capacity=2 push_back(3):size=3,capacity=3 reserve(10):size=3,capacity=10 push_back(4):size=4,capacity=10 pop_back():size=3,capacity=10 resize(5):size=5,capacity=10 shrink_to_fit():size=5,capacity=5

四、关键机制:vector的扩容原理

vector底层是连续的内存空间(和数组一样),这意味着它的内存地址是连续的,无法在原内存后直接追加空间(可能被其他数据占用)。因此:

  1. size超过capacity时,vector自动扩容
    • 步骤1:分配一块更大的连续内存(扩容策略:GCC是1.5倍,MSVC是2倍,目的是减少扩容次数)。
    • 步骤2:将原内存中的所有元素拷贝/移动到新内存。
    • 步骤3:释放原内存。
  2. 扩容的性能开销:拷贝元素+内存分配/释放,因此如果提前知道元素数量,用reserve(n)预留容量可以避免频繁扩容,提升性能。

五、易混淆的resizereserve(结合size/capacity)

这两个函数是操作sizecapacity的核心,很多人容易搞混,这里总结对比:

函数作用对象size的影响capacity的影响
resize(n)size直接设置sizenn>原capacity,则capacity扩容到≥n;否则不变
reserve(n)capacity无影响(size保持不变)n>原capacity,则capacity变为n;否则不变

举例说明

  • vector<int> arr; arr.resize(5);size=5capacity≥5(可直接下标赋值arr[0]=1)。
  • vector<int> arr; arr.reserve(5);size=0capacity=5不能下标赋值arr[0]=1,因为size=0,元素不存在)。

六、总结关键点

  1. size实际元素个数capacity内存能容纳的最大元素个数,且capacity ≥ size
  2. 改变元素数量的操作(如push_backresize)影响size;只有内存重新分配时(如reserve、扩容)才影响capacity
  3. 扩容会带来性能开销,因此已知元素数量时,优先用reserve(n)预留容量,或直接用构造函数/resize设置size
  4. pop_back/erase不会释放内存(capacity不变),若要释放多余内存,可使用shrink_to_fit()(C++11+)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 12:09:18

Vue 3后台管理系统实战宝典:Element Plus Admin高效开发全攻略

Vue 3后台管理系统实战宝典&#xff1a;Element Plus Admin高效开发全攻略 【免费下载链接】element-plus-admin 基于vitetselementPlus 项目地址: https://gitcode.com/gh_mirrors/el/element-plus-admin 想要快速搭建一个专业的企业级后台管理系统吗&#xff1f;基于V…

作者头像 李华
网站建设 2026/4/15 8:13:22

NomNom:No Man‘s Sky存档编辑器的技术实现与应用指南

NomNom&#xff1a;No Mans Sky存档编辑器的技术实现与应用指南 【免费下载链接】NomNom NomNom is the most complete savegame editor for NMS but also shows additional information around the data youre about to change. You can also easily look up each item indivi…

作者头像 李华
网站建设 2026/4/15 9:33:29

Harepacker复活版:MapleStory游戏资源的终极编辑神器

Harepacker复活版&#xff1a;MapleStory游戏资源的终极编辑神器 【免费下载链接】Harepacker-resurrected All in one .wz file/map editor for MapleStory game files 项目地址: https://gitcode.com/gh_mirrors/ha/Harepacker-resurrected 在游戏开发与修改的世界里&…

作者头像 李华
网站建设 2026/4/13 16:24:48

TouchGal:Galgame爱好者的终极社区体验完整指南

TouchGal&#xff1a;Galgame爱好者的终极社区体验完整指南 【免费下载链接】kun-touchgal-next TouchGAL是立足于分享快乐的一站式Galgame文化社区, 为Gal爱好者提供一片净土! 项目地址: https://gitcode.com/gh_mirrors/ku/kun-touchgal-next 在当前数字时代&#xff…

作者头像 李华
网站建设 2026/4/15 6:57:53

PDF-Extract-Kit技巧:提高表格结构识别准确率

PDF-Extract-Kit技巧&#xff1a;提高表格结构识别准确率 1. 背景与挑战&#xff1a;PDF表格提取的痛点 在科研、金融、法律等领域的文档处理中&#xff0c;PDF格式因其版式固定、跨平台兼容性强而被广泛使用。然而&#xff0c;当需要将PDF中的信息数字化时&#xff0c;尤其是…

作者头像 李华
网站建设 2026/4/15 6:57:33

PDF-Extract-Kit设计理念:解决的核心问题

PDF-Extract-Kit设计理念&#xff1a;解决的核心问题 1. 背景与核心挑战 1.1 PDF文档处理的行业痛点 在科研、教育、出版和企业办公等领域&#xff0c;PDF作为最通用的文档格式之一&#xff0c;承载了大量结构化与非结构化的信息。然而&#xff0c;尽管PDF在跨平台展示上具有…

作者头像 李华