首页 >> 要闻简讯 > 学识问答 >

问c 中 vector 的用法详解 C++ 动态数组操作指南

2026-11-04 06:16:41

答

核心结论就是 vector 是 C++ 标准库里面的动态顺序容器,底层本质是一块连续内存的动态数组,和普通固定长度数组最大区别就是 vector 可以自动扩容,不需要提前写死元素个数,能够根据存入数据的数量自动申请释放内存,支持随机访问,尾部插入删除效率很高,头部或者中间插入删除会移动大量元素,效率偏低,使用 vector 需要引入头文件 vector,并且使用 std 命名空间或者写全 stdvector,它是日常开发刷题项目最常用容器,掌握构造初始化,增删改查,迭代器,容量和大小区别,扩容机制,常用算法搭配,就可以覆盖绝大多数开发场景,同时也要清楚 vector 的内存特点,避免迭代器失效,越界访问这些经典坑点。

vector 基础概念与底层原理

vector 内部维护三个核心指针,分别指向内存起始位置,当前有效元素末尾位置,已经分配内存的末尾位置,size 代表当前已经存放元素的有效个数,capacity 代表已经申请好的内存总容量,size 永远小于等于 capacity,当新增元素之后 size 超过 capacity,vector 就会触发扩容,主流编译器一般是按照两倍原有容量重新申请一块更大的连续内存,把旧数据拷贝到新内存,再释放原来旧内存,这个扩容操作成本比较高,所以提前预估元素数量调用 reserve 预分配空间,可以减少多次扩容带来的性能损耗。

构造与初始化方式

初始化方式写法说明适用场景
空 vectorvector v先创建空容器,后续再追加元素
指定个数默认值vector v(10)创建 10 个元素,元素默认初始化为 0
指定个数自定义初值vector v(10,5)创建 10 个元素,全部初始化为 5
数组初始化vector v(arr,arr+5)从普通数组区间拷贝初始化
列表初始化vector v{1,2,3}C++11 之后支持大括号直接填入初始元素
拷贝构造vector v2(v1)用已经存在的 vector 复制一份新容器

常用成员函数清单

增加元素

push_back 在容器尾部追加一个元素,最常用,时间复杂度平均 O1

emplace_back C++11 新增,直接在内存原地构造对象,相比 push_back 减少拷贝,存储自定义类对象的时候性能更好

insert 在指定迭代器位置插入元素,插入位置之后所有元素向后移动,时间复杂度 On

删除元素

pop_back 删除尾部最后一个元素,时间复杂度 O1

erase 根据迭代器删除单个元素或者一段区间元素,删除之后后面元素向前移动

clear 清空全部有效元素,size 变成 0,但是 capacity 保留,内存不会立刻释放

查询访问

operator [] 下标访问,不会做越界检查,速度快

at 下标访问,会做越界校验,越界抛出异常

front 获取第一个元素

back 获取最后一个元素

data 获取底层连续内存首地址,可以兼容 C 风格数组操作

容量相关

size 获取有效元素个数

capacity 获取已经分配内存容量

reserve 预分配 capacity,只扩容不增加 size

resize 修改 size,如果新 size 比原来大,新增元素默认初始化,如果新 size 更小,尾部元素直接丢弃

shrink_to_fit 请求释放多余内存,让 capacity 收缩到和 size 一致,这个是请求,编译器不一定执行

迭代器相关

begin 返回指向第一个元素迭代器

end 返回指向尾后位置迭代器

rbegin rend 反向迭代器,从尾部向前遍历

遍历 vector 的几种写法

第一种 下标 for 循环,适合熟悉数组写法的开发者,for int i 等于 0 i 小于 v.size i 加加

第二种 普通迭代器遍历,for vectorint iterator it 等于 v.begin it 不等于 v.end it 加加

第三种 C++11 范围 for 循环,写法简洁,for auto item v

第四种 搭配 STL 算法,比如 for_each,sort,find,reverse 这些算法直接作用在 vector 区间

重点注意坑点

第一 迭代器失效,扩容之后原来迭代器指针全部失效,insert erase 之后迭代器位置会变化,继续使用旧迭代器会出现野指针崩溃

第二 vector 存储自定义对象,深拷贝浅拷贝问题,扩容拷贝的时候如果类里面有指针成员,没有写拷贝构造会出现内存错误

第三 vector是特殊特化版本,不是普通 bool 数组,不推荐存 bool,行为和普通 vector 有差异

第四 不要频繁在头部 insert,每次插入都要全部元素平移,数据量大的时候性能很差,如果频繁头部插入,优先考虑 deque 容器

实操使用步骤

第一步 引入头文件 include vector,写代码加上 using namespace std 或者前缀 std

第二步 根据业务需求选择对应的构造初始化方式,预估数据量大就提前 reserve 预分配内存

第三步 使用 push_back 或者 emplace_back 追加元素,需要中间插入就调用 insert

第四步 选择合适遍历方式读取元素,使用 at 或者下标做访问

第五步 删除元素使用 erase 或者 pop_back,操作之后及时更新迭代器

第六步 不再使用的时候 vector 离开作用域自动释放内存,不需要手动 delete

总结

vector 是 C++ 标准库动态连续数组,自动扩容,支持随机访问,尾部增删效率高,核心区分 size 和 capacity,掌握各类构造初始化,增删改查成员函数,迭代器遍历,理解扩容机制和迭代器失效问题,就能熟练使用 vector,适合存储连续同类型数据,如果业务是频繁头部插入或者频繁中间大量插入,就需要评估是否更换其他容器。

【相关 FAQ】

问题 1 C 中 vector 和普通数组有什么区别

回答 1 C 里面 vector 是动态容器可以自动扩容,普通数组长度固定,vector 提供大量内置成员函数,普通数组没有封装接口,vector 内存由标准库自动管理,普通数组如果是堆数组需要手动释放内存。

问题 2 C 中 vector 扩容之后为什么迭代器会失效

回答 2 C 中 vector 扩容会申请全新连续内存,拷贝旧数据,原来旧内存被释放,之前保存的迭代器还指向已经释放的旧地址,所以 vector 扩容之后迭代器失效,继续访问会引发程序崩溃。

问题 3 C 中 vector 的 reserve 和 resize 有什么差别

回答 3 C 中 vector 的 reserve 只修改预分配容量 capacity,不会增加有效元素 size,resize 是直接修改有效元素 size,会新增或者删除元素,二者作用对象不一样。

问题 4 C 中 vector 可以存储不同类型的数据吗

回答 4 C 中 vector 是模板容器,同一个 vector 只能存放同一种类型数据,不能在同一个 vector 里面同时存放 int 和 string 这类不同类型元素。

【免责申明】

本内容仅为 C++ vector 用法技术科普,不同编译器版本对 vector 实现细节存在差异,代码编译运行以实际编译器标准为准,本教程不保证所有极端场景代码都无 bug,仅作为学习参考。

 

相关阅读

最新文章