vector::erase删除元素后原迭代器失效,应使用其返回值更新迭代器;clear()不清内存,可用swap或shrink_to_fit()释放;erase区间为左闭右开,需确保first≤last。

vector::erase 删除单个或连续元素时,迭代器会失效
调用 erase 后,被删位置及其之后所有元素向前移动,原迭代器指向的内存已无效。常见错误是边遍历边 erase 还继续 ++ 迭代器:
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it == 3) v.erase(it); // ❌ 崩溃:it 失效后 ++ 是未定义行为
}
正确写法是用 erase 的返回值(指向下一个有效位置):
-
v.erase(it)返回新的有效迭代器,应直接赋给it - 删除后不执行
++it,否则跳过下一元素 - 若需条件删除多个,推荐 while 循环 + 返回值处理
示例:
auto it = v.begin();
while (it != v.end()) {
if (*it == 3) it = v.erase(it); // ✅ 返回下一个位置
else ++it;
}
clear() 只清空内容,不释放内存
clear() 将 size() 置为 0,但 capacity() 不变,底层分配的内存仍保留。这对频繁增删且尺寸波动大的场景可能造成内存浪费。
立即学习“C++免费学习笔记(深入)”;
- 想真正释放内存,可配合 swap 技巧:
vector(v).swap(v); - C++11 起也可用
shrink_to_fit()(非强制,只是请求),但不保证成功 -
clear()时间复杂度是 O(n),因需调用每个元素的析构函数;对 trivial 类型(如 int)无实际开销
erase 删除多个元素要传入 [first, last) 区间
erase 重载支持删除一段连续元素,参数是两个迭代器,**左闭右开**。容易误传相同迭代器或顺序颠倒:
-
v.erase(v.begin(), v.begin() + 2)删除前两个元素 -
v.erase(v.begin(), v.begin())是合法空操作,不崩溃 -
v.erase(v.begin() + 2, v.begin())❌ 行为未定义,必须确保 first ≤ last - 若用下标计算区间,注意越界检查:
pos + n
批量删除某值的所有出现(C++11 起更推荐 erase–remove 惯用法):
v.erase(std::remove(v.begin(), v.end(), 42), v.end()); // 删除所有 42
vector 删除操作的性能和异常安全细节
删除操作性能取决于元素类型和位置:
- 尾部删除(
pop_back())是 O(1),最快;头部或中部删除是 O(n),因需移动后续元素 - 若元素类型析构函数抛异常,
erase和clear可能中途停止,已析构部分不会回滚(C++ 标准不保证强异常安全) - 对指针 vector(如
vector),erase不释放指针所指内存,需手动处理 - 使用
reserve()预分配后,clear()不影响 capacity,但多次erase后若 size 显著减小,记得shrink_to_fit()
最易忽略的是:用下标访问前没检查 size(),而 erase 可能使 vector 变空——所有基于 size 的逻辑都得重新校验。










