erase()用于删除vector中指定位置元素,需传入迭代器(如vec.begin()+index),不接受整数下标;越界访问行为未定义,须预先检查索引有效性。

用 erase() 删除指定索引位置的元素
直接调用 vector::erase(),传入指向目标位置的迭代器即可。注意它不接受下标整数,必须转成迭代器:vec.erase(vec.begin() + index)。如果 index 超出范围(比如 ≥ vec.size()),行为未定义——多数实现会崩溃或静默越界写,务必提前检查。
常见错误现象:程序在调试模式下抛 std::out_of_range 或直接 segfault;Release 模式下可能看似正常但实际破坏内存。
- 安全写法:
if (index - 删除最后一个元素时,
vec.erase(vec.end() - 1)合法,但vec.erase(vec.end())是未定义行为 -
erase()返回下一个有效迭代器,可用于连续删除(如删所有偶数索引),但单次删除通常不需要接返回值
删除多个连续位置用 erase() 区间重载
要删从 start 到 end-1(左闭右开)的一段,写成 vec.erase(vec.begin() + start, vec.begin() + end)。这个操作是 O(n) 时间复杂度,因为后续元素要整体前移。
容易踩的坑:第二个参数是「末尾之后的位置」,不是「结束索引」。比如删第 2 和第 3 个元素(索引 1 和 2),应写 erase(begin+1, begin+3),而不是 erase(begin+1, begin+2)。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 若
start > end,结果未定义;若end > vec.size(),同样崩溃 - 删除后原
end之后的元素索引全部减小,别在循环里边删边用原始下标遍历 - 大量连续删除时,考虑先标记再批量
erase,避免反复移动内存
想按值删除而不是按位置?别误用 erase()
erase() 本身不查值,它是纯位置操作。如果目标是“删掉第一个值为 x 的元素”,得组合 std::find:auto it = std::find(v.begin(), v.end(), x); if (it != v.end()) v.erase(it);
常见混淆:有人写 v.erase(x) —— 编译直接失败,因为 erase() 没有接受值的重载。
- 删所有等于
x的元素:用erase-remove惯用法:v.erase(std::remove(v.begin(), v.end(), x), v.end()); -
std::remove不真正删除,只是把保留元素移到前面并返回新逻辑结尾;erase才真正缩短容器 - 自定义类型需确保
operator==可用,否则std::find或std::remove编译不过
性能和异常安全要注意什么
erase() 对于非 trivial 类型(比如含指针、文件句柄的对象),会调用被删元素的析构函数;对 trivial 类型(如 int)则只是内存平移。移动后续元素的过程不会抛异常(C++11 起保证强异常安全)。
但有一个隐性成本:每次 erase 都触发一次内存复制。如果要删很多分散位置的元素(比如删索引 5、17、23),反复调用 erase 效率极低——后面每次都要搬动大量数据。
- 优化建议:收集所有待删索引,排序去重,倒序删除(避免索引偏移),或改用「标记 + 重建」策略
- 如果容器很大且删除频繁,考虑换
std::list或std::deque,但注意它们的随机访问是 O(n) -
vector删除后容量(capacity())不变,内存没释放;需要缩容得手动shrink_to_fit()
删位置这事看着简单,但越早检查 index 是否越界、越清楚 erase 的迭代器语义,后面越不容易半夜被 core dump 叫醒。

















