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= 连续内存 + 自动扩容的动态数组

相关推荐
qeen872 天前
【C++】vector的模拟实现详解(二)
c++·学习·算法·迭代器·stl
红豆诗人3 天前
C++ string 和 vector 基础:从常用接口到模拟实现
c++·stl
鱼子星_3 天前
【C++】vector
开发语言·c++·笔记·stl
阿米亚波6 天前
【C++ STL】std::forward_list
开发语言·c++·笔记·stl·visual studio·forward_list
阿米亚波8 天前
【C++ STL】std::list
c++·windows·笔记·stl·list
阿米亚波10 天前
【C++ STL】std::deque
数据结构·c++·笔记·算法·stl
CHHH_HHH11 天前
【C++11】深入解析C++可变参数模板
开发语言·c++·算法·stl·c++11
qeen8711 天前
〖C++〗STL简介:发展历史、六大组件与简单应用
c++·学习·stl·模板
知无不研12 天前
用c++写一个简单vector
开发语言·数据结构·c++·stl