一、std::vector
简介
std::vector
是 C++ STL 中最常用的动态数组容器 ,特点是:
支持 随机访问 内存是 一块连续的空间 自动扩容,支持添加和删除元素
# include <vector>
# include <iostream>
二、常见用法
1. 初始化
std:: vector< int > v1;
std:: vector< int > v2 ( 5 ) ;
std:: vector< int > v3 ( 5 , - 1 ) ;
std:: vector< int > v4 = { 1 , 2 , 3 , 4 } ;
2. 添加元素
v1. push_back ( 10 ) ;
3. 遍历元素
for ( size_t i = 0 ; i < v1. size ( ) ; ++ i)
std:: cout << v1[ i] << " " ;
for ( int x : v1)
std:: cout << x << " " ;
for ( auto it = v1. begin ( ) ; it != v1. end ( ) ; ++ it)
std:: cout << * it << " " ;
4. 常用操作
v1. size ( ) ;
v1. empty ( ) ;
v1. clear ( ) ;
v1. back ( ) ;
v1. front ( ) ;
三、resize()
vs reserve()
的区别
函数 作用 影响大小 影响容量 初始化元素 resize(n)
直接改变 size,增大时会初始化元素 ✅ ✅ ✅ 默认值 reserve(n)
预留容量,不改变 size ,不初始化元素 ❌ ✅ ❌
std:: vector< int > v;
v. reserve ( 5 ) ;
v. resize ( 3 ) ;
四、性能分析
1. 添加元素性能
std:: vector< int > v;
for ( int i = 0 ; i < 1e6 ; ++ i) {
v. push_back ( i) ;
}
每次扩容会分配新内存并拷贝旧数据 为避免频繁扩容,可提前 reserve(n)
2. 与 std::deque
比较
操作 vector
deque
push_back ✅ 快 ✅ 快 push_front ❌ 非常慢 ✅ 快 随机访问 ✅ 高效(连续内存) ✅ 稍慢(分块) 遍历性能 ✅ 最优 ❌ 缓存命中较差
3. 与 std::list
比较
操作 vector
list
随机访问 ✅ 支持 ❌ 不支持 中间插入 ❌ 慢(移动元素) ✅ 快(常数时间) 遍历性能 ✅ 好 ❌ 差(非局部访问)
五、注意事项
注意点 建议 内存连续 不要随意返回 vector
的 data()
指针给外部长期持有 插入性能 插入大量数据前建议 reserve()
指针/引用失效 扩容时旧地址会失效 resize()
构造新对象对类对象注意构造/析构成本 push_back
后地址失效扩容时原指针、引用都失效!避免用裸指针 频繁插入中间位置慢 插入/删除中间元素为 O(n),性能差 clear()
不回收内存清空元素但不会减少容量 shrink_to_fit()
不可靠提交释放容量,但具体行为平台相关
指针失效示例
std:: vector< int > v = { 1 , 2 , 3 } ;
int * ptr = & v[ 0 ] ;
v. push_back ( 4 ) ;
六、综合使用示例
1. 保存类对象
struct Point {
float x, y;
} ;
std:: vector< Point> points;
points. emplace_back ( 1.0f , 2.0f ) ;
2. 用作二维数组
std:: vector< std:: vector< int >> matrix ( 3 , std:: vector< int > ( 4 , 0 ) ) ;
3. 与 std::shared_ptr
配合
std:: vector< std:: shared_ptr< Point>> vec;
vec. push_back ( std:: make_shared< Point> ( ) ) ;
4. 使用 std::move
提高性能:
std:: vector< std:: string> v;
std:: string s = "hello" ;
v. push_back ( std:: move ( s) ) ;
5. 使用 std::vector<bool>
的陷阱:
它是位压缩优化版 ,不是普通的 bool 数组 有时会导致不能获取引用/指针
建议避免使用它,或用 std::vector<char>
替代。
6. 快速可视化 size
与 capacity
增长
std:: vector< int > v;
for ( int i = 0 ; i < 100 ; ++ i) {
v. push_back ( i) ;
std:: cout << "Size: " << v. size ( )
<< ", Capacity: " << v. capacity ( ) << std:: endl;
}
7. 固定长度数组的模拟:
std:: vector< int > data ( 100 , 0 ) ;
8. 避免重复分配:
std:: vector< std:: string> names;
names. reserve ( 1000 ) ;
for ( . . . ) {
names. emplace_back ( . . . ) ;
}
std::vector
是一个自动管理内存的容器 ,但它的内存释放行为可能不是你预期的 :即使你调用了 clear()
,它也不会释放 capacity 对应的内存 。
七、std::vector对象内存释放
std::vector
常见的释放方式总结如下。
方法 作用 内存是否释放 clear()
清除所有元素 ❌ 不释放内存(capacity 保留) shrink_to_fit()
请求释放多余内存 ✅ 释放未使用容量(非强制) swap()
与空 vector 交换,强制释放 ✅✅ 推荐方式 std::vector<T>().swap(vec)
简写版强制释放 ✅✅ 推荐方式
示例演示
示例 1:clear()
不释放内存
std:: vector< int > v ( 10000 ) ;
std:: cout << "Before clear: size = " << v. size ( )
<< ", capacity = " << v. capacity ( ) << "\n" ;
v. clear ( ) ;
std:: cout << "After clear: size = " << v. size ( )
<< ", capacity = " << v. capacity ( ) << "\n" ;
输出可能是:
Before clear: size = 10000, capacity = 10000
After clear: size = 0, capacity = 10000
示例 2:推荐做法 — 与空 vector 交换
std:: vector< int > v ( 10000 ) ;
std:: vector< int > ( ) . swap ( v) ;
示例 3:使用 shrink_to_fit()
std:: vector< int > v ( 10000 ) ;
v. clear ( ) ;
v. shrink_to_fit ( ) ;
注意:shrink_to_fit()
是 non-binding request ,标准库实现可以选择忽略 这个请求。
总结建议
目标 推荐操作 清除数据,但保留内存用于重用 clear()
清除数据 + 建议释放内存 clear(); shrink_to_fit();
清除数据 + 强制释放所有内存 std::vector<T>().swap(vec);
高级应用建议
在循环中避免反复构造销毁大 vector,建议:vec.clear();
+ reserve(n);
预分配 如果 vector
是类成员,析构中使用 swap 强制释放空间更彻底 用于缓存图像帧 / 点云数据时,vector.swap()
能快速释放大块内存
八、小结
特性 结论 内存模型 连续 访问方式 支持随机访问 插入效率 后端高效,中间慢 替代容器建议 若需头部插入:用 deque
;频繁中间操作:用 list
调优建议 reserve()
可提升性能;避免频繁扩容连续内存,兼容 C 数组 中间插入慢,扩容成本高 标准接口统一 需要手动管理扩容策略 与 Eigen
、OpenCV cv::Mat
等兼容性高 无法支持双端插入