九江市网站建设_网站建设公司_悬停效果_seo优化
2026/1/11 7:56:49 网站建设 项目流程

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

文章目录

      • 一、核心比喻(快速理解)
      • 二、正式定义与特点
        • 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+)。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询