1. 为什么我们需要动态数组
在C++编程中,数组是最基础的数据结构之一。传统C风格数组虽然简单直接,但存在一个致命缺陷——大小固定。想象一下你正在开发一个学生成绩管理系统,最初你预估班级最多50人,于是声明了int scores[50]。但当新学期开始,班级扩招到60人时,这个固定大小的数组就无能为力了。
这就是vector存在的意义。作为STL中最常用的序列容器,vector完美解决了静态数组的痛点。它就像一个有弹性的储物箱,随着你放入物品的增多,箱子会自动扩容,完全不需要你手动管理内存。我十年前刚接触C++时,就因为手动管理动态数组内存导致内存泄漏,调试了整整两天。自从使用vector后,这类问题再没出现过。
vector内部通过动态分配的连续内存空间实现。当现有空间不足时,它会自动申请更大的内存块(通常是原大小的1.5或2倍),将原有元素搬移到新空间,然后释放旧内存。这个过程对使用者完全透明,你只需要不断地push_back,剩下的交给vector处理。
关键提示:虽然vector能自动扩容,但频繁扩容会导致性能损耗。在知道元素大致数量的情况下,建议先用reserve()预分配空间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. vector的核心特性解析
2.1 底层实现机制
vector的魔法在于它巧妙地平衡了数组的随机访问特性和动态扩容能力。它的底层仍然是一块连续内存,这使得它保持了与普通数组相同的O(1)随机访问时间复杂度。但与普通数组不同的是,vector维护了三个关键指针:
_start:指向内存块起始位置_finish:指向最后一个元素的下一个位置_end_of_storage:指向内存块的末尾
这种设计使得size()和capacity()可以高效计算:
cpp复制size() = _finish - _start
capacity() = _end_of_storage - _start
2.2 迭代器失效问题
vector使用中最容易踩坑的就是迭代器失效。当发生扩容时,所有迭代器、指针和引用都会失效。我曾在一个项目中因为忽略这点导致程序随机崩溃。看这个例子:
cpp复制vector<int> v = {1,2,3};
auto it = v.begin();
v.push_b
