C++ STL 容器详解:vector

一、vector 简介

1.1 什么是 vector?

vector 是 C++ STL(标准模板库)中的一种动态数组容器

它本质上是一块连续的动态内存空间,可以:

  • 自动扩容

  • 随机访问

  • 在尾部高效插入删除

  • 保存任意类型的数据

例如:

复制代码
#include <vector>

using namespace std;

int main()
{
    vector<int> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    return 0;
}

此时:

复制代码
v
┌───┬───┬───┐
│ 1 │ 2 │ 3 │
└───┴───┴───┘

vector 内部保存三个整数。


二、vector 的底层原理

理解 vector 最重要的是理解它的三个成员:

复制代码
start
finish
end_of_storage

可以理解为:

复制代码
        capacity空间

start                  end_of_storage
 ↓                          ↓
 ┌────┬────┬────┬────┬────┐
 │ 10 │ 20 │ 30 │    │    │
 └────┴────┴────┴────┴────┘
      ↑              ↑
   finish       可扩容空间

三个指针:

成员 作用
start 指向数组开始
finish 指向有效元素末尾
end_of_storage 指向申请空间末尾

size 和 capacity 区别

这是 vector 高频考点。

size()

表示:

当前已经存储多少个元素

例如:

复制代码
vector<int> v;

v.push_back(10);
v.push_back(20);

cout << v.size();

输出:

复制代码
2

capacity()

表示:

当前申请了多少内存空间

例如:

复制代码
vector<int> v;

v.push_back(10);

cout << v.capacity();

可能输出:

复制代码
1

也可能:

复制代码
2

因为不同编译器扩容策略不同。


例如:

复制代码
vector<int> v;

v.push_back(1);
v.push_back(2);
v.push_back(3);

可能:

复制代码
size = 3

capacity = 4

内存:

复制代码
capacity=4

┌───┬───┬───┬───┐
│ 1 │ 2 │ 3 │   │
└───┴───┴───┴───┘

三、vector 的初始化方式


3.1 默认初始化

复制代码
vector<int> v;

创建空 vector:

复制代码
size=0
capacity=0

3.2 指定大小

复制代码
vector<int> v(5);

创建 5 个元素:

复制代码
0 0 0 0 0

3.3 指定大小和值

复制代码
vector<int> v(5,10);

结果:

复制代码
10 10 10 10 10

3.4 使用数组初始化

复制代码
int arr[]={1,2,3,4};

vector<int> v(arr,arr+4);

结果:

复制代码
1 2 3 4

3.5 拷贝构造

复制代码
vector<int> v1{1,2,3};

vector<int> v2(v1);

两个 vector 独立:

复制代码
v1:
1 2 3


v2:
1 2 3

修改 v2:

复制代码
v2[0]=100;

不会影响 v1。

因为 vector 使用:

深拷贝


四、vector 常用接口大全


4.1 push_back()

尾插元素

复制代码
vector<int> v;

v.push_back(10);
v.push_back(20);

结果:

复制代码
10 20

时间复杂度:

复制代码
O(1)

平均情况下。


4.2 pop_back()

删除尾部元素

复制代码
v.pop_back();

例如:

复制代码
10 20 30

删除:

复制代码
10 20

注意:

只能删除最后一个。


4.3 size()

获取元素个数

复制代码
cout<<v.size();

返回:

复制代码
size_t

4.4 empty()

判断是否为空

复制代码
if(v.empty())
{
    cout<<"空";
}

返回:

复制代码
true / false

4.5 clear()

清空元素

复制代码
v.clear();

例如:

之前:

复制代码
1 2 3 4

之后:

复制代码

注意:

clear 不一定释放空间。

例如:

复制代码
vector<int> v(100);

v.clear();

cout<<v.capacity();

可能:

复制代码
100

4.6 reserve()

提前开空间

复制代码
vector<int> v;

v.reserve(100);

表示:

提前申请100个元素空间。

例如:

没有 reserve:

复制代码
1
2
4
8
16
32
...

不断扩容。

使用 reserve:

复制代码
capacity=100

减少扩容次数。


reserve 注意

复制代码
vector<int> v;

v.reserve(100);

cout<<v.size();

输出:

复制代码
0

因为:

reserve 只改变 capacity。

不会创建元素。


4.7 resize()

改变元素数量

例如:

复制代码
vector<int> v;

v.resize(5);

结果:

复制代码
0 0 0 0 0

指定值:

复制代码
v.resize(5,10);

结果:

复制代码
10 10 10 10 10

区别:

函数 作用
reserve 扩容空间
resize 改变元素数量

五、vector 的访问方式


5.1 operator\[\]

复制代码
vector<int> v={1,2,3};


cout<<v[0];

输出:

复制代码
1

特点:

不检查越界。

例如:

复制代码
v[10];

可能崩溃。


5.2 at()

复制代码
cout<<v.at(0);

特点:

检查越界。

例如:

复制代码
v.at(10);

抛异常:

复制代码
out_of_range

5.3 front()

访问第一个元素

复制代码
cout<<v.front();

5.4 back()

访问最后一个元素

复制代码
cout<<v.back();

六、vector 迭代器

迭代器是 STL 的核心。

vector 迭代器类似指针。


6.1 begin()

开始位置

复制代码
vector<int>::iterator it=v.begin();

指向:

复制代码
第一个元素

6.2 end()

结束位置

复制代码
v.end();

注意:

end 指向最后一个元素后面。

例如:

复制代码
1 2 3

^     ^
|     |
begin end

遍历 vector

方法1:普通 for

复制代码
for(size_t i=0;i<v.size();i++)
{
    cout<<v[i];
}

方法2:迭代器

复制代码
vector<int>::iterator it=v.begin();


while(it!=v.end())
{
    cout<<*it<<" ";
    it++;
}

方法3:范围 for

C++11:

复制代码
for(auto e:v)
{
    cout<<e;
}

七、vector 插入和删除


7.1 insert()

指定位置插入

例如:

复制代码
vector<int> v={1,2,3};


v.insert(v.begin()+1,100);

结果:

复制代码
1 100 2 3

时间复杂度:

复制代码
O(N)

因为需要移动元素。


7.2 erase()

删除指定位置

复制代码
v.erase(v.begin()+1);

例如:

复制代码
1 2 3

删除2:

复制代码
1 3

删除区间:

复制代码
v.erase(v.begin(),v.begin()+2);

删除:

复制代码
前两个元素

八、vector 扩容机制(重点)

当空间不足:

例如:

复制代码
capacity=3

1 2 3

继续:

复制代码
push_back(4);

发生:

  1. 申请更大的空间

  2. 拷贝旧数据

  3. 释放旧空间

  4. 插入新数据

过程:

复制代码
旧空间

1 2 3


↓

新空间

1 2 3 _ _ _


↓

释放旧空间

为什么 vector 扩容不是一点一点增加?

因为:

如果每次增加1:

插入n个元素:

需要大量搬迁。

效率:

复制代码
O(n²)

所以通常采用:

复制代码
2倍扩容

达到:

均摊 O(1)


九、vector 的深浅拷贝

vector 内部:

保存:

复制代码
指针
数据
容量

如果浅拷贝:

复制代码
v1

↓

同一块空间

↑

v2

会造成:

  • 修改互相影响

  • double free

所以 vector 使用:

深拷贝

例如:

复制代码
vector<int> v1={1,2,3};

vector<int> v2=v1;

内存:

复制代码
v1:

1 2 3


v2:

1 2 3

两个空间独立。


十、vector 失效问题(面试重点)

10.1 扩容导致迭代器失效

复制代码
vector<int> v={1,2,3};

auto it=v.begin();


v.push_back(4);


cout<<*it;

可能错误。

原因:

扩容后:

旧空间释放。

原 iterator 指向:

复制代码
已经释放的地址

10.2 erase导致迭代器失效

复制代码
auto it=v.begin();

v.erase(it);

之后:

it 不可使用。


十一、vector 与数组区别

数组 vector
大小 固定 动态
内存 栈区 堆区
扩容 不能 可以
效率 略低
安全性

十二、vector 与 list 区别

vector list
底层 连续数组 链表
随机访问
插入删除 中间慢
缓存友好

十三、vector 性能分析

操作 复杂度
随机访问 O(1)
尾插 O(1)
尾删 O(1)
头插 O(N)
中间插入 O(N)
查找 O(N)

十四、vector 模拟实现(核心思想)

简单版本:

复制代码
template<class T>
class Vector
{
public:

    Vector()
    {
        _start=nullptr;
        _finish=nullptr;
        _end=nullptr;
    }


private:

    T* _start;
    T* _finish;
    T* _end;

};

三个指针:

复制代码
_start

 ↓

[1][2][3][ ][ ]

       ↑
    finish

              ↑
          end

这就是 STL vector 的核心结构。


十五、vector 高频面试题

1.vector 为什么支持随机访问?

因为:

底层是连续数组。

可以:

复制代码
地址=首地址+下标*sizeof(type)

2.vector 为什么尾插效率高?

因为:

尾部空间直接写入。


3.vector 扩容为什么消耗大?

因为:

需要:

  • 申请新空间

  • 拷贝数据

  • 释放旧空间


4.reserve 和 resize区别?

答案:

复制代码
reserve:
改变容量

resize:
改变元素数量

5.vector 如何释放空间?

方法:

复制代码
vector<int>().swap(v);

原理:

创建临时空 vector

交换资源。


总结

vector 是 C++ STL 中最重要的容器之一。

核心知识:

  1. vector 是动态数组

  2. 底层是一块连续空间

  3. 使用三个指针管理数据

  4. size 表示元素数量

  5. capacity 表示容量

  6. 扩容会导致迭代器失效

  7. 尾插效率高

  8. 中间插入删除效率低

  9. 支持随机访问

  10. STL 中大量算法基于 vector

相关推荐
一木 之林4 小时前
插件、MCP、Skill 的区别?
java·c++·人工智能
可乐鸡翅yeah_4 小时前
hls.js 播放质量埋点实战,采集卡顿、起播、错误指标定位线上用户问题
开发语言·前端·javascript·ecmascript·音视频·m3u8·音视频在线播放
szarron4 小时前
RF Demo Kit|NanoVNA 射频演示测试板完整上手教程,滤波器、衰减器、SOLT 校准学习板
开发语言·人工智能·学习·php·射频工程·频谱仪
边境悍匪4 小时前
蜗牛学苑 Java 智能体学习 Day39|SpringAI 会话存储、Function‑Call 工具调用、MCP 思维导图复盘
java·开发语言·spring boot·学习·阿里云
ShineWinsu4 小时前
对于MySQL:内置函数的解析
linux·数据库·c++·mysql·面试·函数·查询
万物智能信息科技4 小时前
RK3568 的多路显示移植—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
linux·开发语言·华为·开源·harmonyos
蓝悦无人机5 小时前
Qt Design Studio(QDS)4.8.2项目文件结构详解
开发语言·qt·qt creator·qds·项目文件结构·qtc
yxlalm5 小时前
4.java秒杀项目第四课-后端商品后台接口
java·开发语言
孙启超5 小时前
【AI开发之Rust】第 1 课:认识 Rust 与开发环境 —— 装好工具链,跑通第一个程序
开发语言·人工智能·后端·ai·rust·安全架构
君顾15 小时前
家政派单小程序源码开发实战:从零搭建到上线全流程指南
java·开发语言·家政派单