STL之Vector

一、std::vector概述

std::vector是一个连续存储的动态数组 ,位于头文件 <vector>中,属于 C++ 标准模板库(STL)的序列式容器。

复制代码
#include <vector>
using namespace std;

vector<int> v;

核心特点

  • 连续内存:元素在内存中是连续存放的

  • 动态扩容:容量可自动增长

  • 随机访问 :支持 O(1)下标访问

  • 尾部操作高效push_back/ pop_back摊销 O(1)

  • 中间插入/删除代价较高:需要移动元素


二、std::vector的基本用法

1. 构造方式

复制代码
vector<int> v1;                  // 空 vector
vector<int> v2(10);              // 10 个元素,默认初始化为 0
vector<int> v3(10, 5);           // 10 个 5
vector<int> v4 = {1, 2, 3, 4};   // 初始化列表
vector<int> v5(v4);              // 拷贝构造

2. 元素访问

复制代码
v[0];        // 不检查越界
v.at(0);     // 越界抛异常
v.front();   // 首元素
v.back();    // 尾元素

3. 容量相关

复制代码
v.size();      // 当前元素个数
v.capacity();  // 当前已分配容量
v.empty();     // 是否为空
v.reserve(100); // 预分配容量
v.resize(50);   // 改变元素数量

4. 修改操作

复制代码
v.push_back(10);
v.pop_back();

v.insert(v.begin() + 1, 99); // 在下标 1 处插入
v.erase(v.begin() + 1);      // 删除下标 1 的元素

v.clear();                   // 清空元素

三、vector的内存布局

1. 逻辑视图

复制代码
索引:      0   1   2   3   4
数据:     [10][20][30][40][50]

2. 物理内存布局(关键)

vector内部通常包含三个指针(或等价结构):

复制代码
begin ──► [ e0 ][ e1 ][ e2 ][ e3 ][ e4 ] ... (未初始化空间)
            ↑                        ↑
          size                     capacity
  • size:当前元素个数

  • capacity:已分配内存可容纳的最大元素数

3. 内存连续性

  • 所有元素在内存中连续排列

  • 这一点与 listmap等节点式容器形成鲜明对比

  • 因此:

    • 支持指针偏移访问

四、扩容机制(重点)

1. 何时发生扩容?

当执行:

复制代码
v.push_back(x);

若:

复制代码
size == capacity

则触发扩容。

2. 扩容过程

  1. 分配一块更大的新内存(通常是原容量的 1.5 倍或 2 倍

  2. 将旧元素拷贝或移动到新内存

  3. 释放旧内存

  4. 更新内部指针

⚠️ 扩容会导致:

  • 所有迭代器、指针、引用失效

3. 为什么扩容代价高?

  • 内存分配本身慢

  • 元素拷贝成本高(尤其对象类型)

✅ 解决方案

复制代码
v.reserve(1000); // 提前预留空间

五、reservevs resize

函数 作用
reserve(n) 只改变容量,不改变 size
resize(n) 改变元素数量

示例:

复制代码
v.reserve(100); // v.size() == 0
v.resize(100);  // v.size() == 100

六、vector的性能特征

时间复杂度

操作 复杂度
随机访问 O(1)
尾插 / 尾删 摊销 O(1)
中间插入 O(n)
查找 O(n)

适用场景

✅ 适合:

  • 频繁随机访问

  • 尾部增删

  • 已知大致数据规模

❌ 不适合:

  • 频繁在头部或中间插入

  • 大量小对象频繁扩容


七、常见陷阱与注意事项

1. 迭代器失效

复制代码
for (auto it = v.begin(); it != v.end(); ++it) {
    if (*it == 3)
        v.push_back(10); // ❌ 可能失效
}

✅ 正确做法:使用索引或在循环外修改


2. vector<bool>的特殊性

复制代码
vector<bool> vb(10);
bool& x = vb[0]; // ❌ 编译错误

原因:vector<bool>是位压缩实现,不是真正的 bool容器。

✅ 替代方案:

复制代码
vector<char>
deque<bool>

八、总结

  • std::vector连续内存、动态扩容的顺序容器

  • 内部通过 size + capacity管理内存

  • 扩容代价高,推荐提前 reserve

  • 适合大多数"数组型"需求

一句话总结:

vector= 连续内存 + 自动扩容的动态数组

相关推荐
我不会插花弄玉2 天前
15.map,set下:AVL树,红黑树和map,set的封装【由浅入深-C++】
c++·stl
ShineWinsu2 天前
对于C++中unordered_map的详细介绍
数据结构·c++·算法·面试·stl·哈希表·unordered_map
鱼子星_3 天前
【C++】stack和queue的应用及其模拟实现:适配器与容器适配器
数据结构·c++·笔记·stl
lingran__3 天前
C++ STL 关联式容器万字详解:set、multiset、map、multimap|接口用法 + 易错点 + 力扣真题实战
开发语言·c++·stl·set·map·红黑树·关联式容器
程序喵大人7 天前
【C++进阶】STL容器与迭代器 - 10 把容器、迭代器和数据流串成一个小程序
开发语言·c++·容器·小程序·迭代器·stl
誰能久伴不乏9 天前
深入解析 C++ STL 底层原理:从设计哲学到内存收割机
c++·架构·stl
阿米亚波10 天前
【C++ STL】std::unordered_multiset
开发语言·数据结构·c++·笔记·stl
阿米亚波11 天前
【C++ STL】std::unordered_multimap
开发语言·数据结构·c++·笔记·stl
程序喵大人11 天前
【C++进阶】STL容器与迭代器 - 08 插入删除之后,哪些迭代器会失效
开发语言·c++·容器·迭代器·stl
鱼子星_11 天前
【C++】深入剖析list:list及其双向迭代器实现
开发语言·数据结构·c++·笔记·stl·list