用erase删除元素后迭代器会失效

在尝试计算两个整数数组的交集时,使用迭代器遍历并删除相同元素时出现了AddressSanitizer负大小参数错误。错误发生在尝试删除元素后继续迭代的过程中,可能由于删除操作导致迭代器失效。问题在于同时删除了`it1`和`it2`,而`it2`可能已因`it1`的删除变为无效。解决方案可能是只删除一个迭代器指向的元素,然后安全地移动另一个迭代器。

做一道求两数组交集的题目时我用迭代器遍历两个数组,并在迭代中用了erase操作,有了下面的报错

=================================================================
==42==ERROR: AddressSanitizer: negative-size-param: (size=-120)
    #5 0x7f52c5b84082  (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
0x602000000114 is located 4 bytes inside of 8-byte region [0x602000000110,0x602000000118)
allocated by thread T0 here:
    #6 0x7f52c5b84082  (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
==42==ABORTING

错误代码如下

for(vector<int>::iterator it1=nums1.begin();it1 !=nums1.end();)
        {
            for(vector<int>::iterator it2=nums2.begin();it2 !=nums2.end();)
            {
                if(*it1==*it2)
                {
                    com.push_back(*it1);
                    nums1.erase(it1);
                    nums1.erase(it2);
                    continue;
                }
                it2++;

            }
            it1++;
        }

补充一点 可以利用迭代器修改vector元素

vector<int>v1;
v1.push_back(10);
vector<int>::iterator it = v1.begin();
*it = 12;
cout<<*it;

v1先插入的元素10被修改为了12

<think> 我们参考了引用的内容,特别是引用[2]、[3]、[5]中关于vector遍历删除元素迭代器失效问题的描述。 根据引用[2]和[3]:当使用erase删除元素时,被删除元素之后的迭代器失效,包括删除最后一个元素导致迭代器指向end()(一个无效位置)。 引用[5]给出了一个正确的做法:在删除元素时,利用erase的返回值(返回被删除元素的下一个有效迭代器)来更新迭代器,这样就不会造成失效。 因此,解决vector遍历删除元素迭代器失效问题的方法是: 在循环中,当删除元素时,将迭代器更新为erase的返回值(即下一个有效迭代器);当不删除元素时,才将迭代器自增。 具体步骤: 1. 使用迭代器遍历vector,循环条件为 iter != vec.end() 2. 在循环体内,检查当前元素是否需要删除 3. 如果需要删除,则调用iter = vec.erase(iter); 此时iter已经被更新为指向下一个元素(或者end()4. 如果不需要删除,则执行iter++,指向下一个元素。 注意:不能使用基于范围的for循环(如引用[3]中的例子一),因为这种循环内部隐藏了迭代器的自增操作,我们无法在删除后控制迭代器。 下面给出一个代码示例(参考引用[5]): </think> 在 C++ 中解决 `vector` 遍历删除元素时的迭代器失效问题,关键在于正确处理 `erase()` 方法返回的新迭代器。以下是具体方法和步骤: ### 🔍 核心解决方法 1. **更新迭代器** `erase()` 会返回**被删除元素下一个位置的有效迭代器**,必须接收此返回值更新迭代器: ```cpp auto it = vec.begin(); while (it != vec.end()) { if (condition) { it = vec.erase(it); // ✅ 正确:用返回值更新迭代器 } else { ++it; // 未删除时手动递增 } } ``` 2. **禁用 `for` 循环自增** 避免在循环条件中自增迭代器,否则会跳过元素或访问失效迭代器: ```cpp // ❌ 错误示例(迭代器失效) for (auto it = vec.begin(); it != vec.end(); ++it) { if (*it == target) { vec.erase(it); // 未接收返回值,it 失效 } } ``` ### ⚠️ 特殊场景处理 - **删除最后一个元素** 当删除末尾元素时,`erase()` 返回 `end()`,循环条件 `it != vec.end()` 自动终止,避免越界[^2]。 - **连续删除相邻元素** 利用 `erase()` 返回值自动指向下一元素,无需额外递增: ```cpp // 删除所有偶数 vector<int> vec = {2,3,4,5,6}; auto it = vec.begin(); while (it != vec.end()) { if (*it % 2 == 0) { it = vec.erase(it); // 删除后 it 已指向下一元素 } else { ++it; } } // 结果:vec = {3,5} ``` ### 📝 完整代码示例 ```cpp #include <vector> #include <iostream> using namespace std; int main() { vector<int> vec = {1,0,2,0,3,0}; auto it = vec.begin(); while (it != vec.end()) { if (*it == 0) { it = vec.erase(it); // 更新迭代器 } else { ++it; } } // 输出:1 2 3 for (int num : vec) cout << num << " "; return 0; } ``` ### 💡 失效原因总结 1. **内存重分配** 删除元素可能导致内存重新分配,原有迭代器指向被释放的内存[^1]。 2. **元素移动** 删除中间元素后,后续元素前移,迭代器指向错误位置[^4]。 3. **末尾删除** 删除最后一个元素后,迭代器指向 `end()`(无效位置)[^2]。 > 📌 **关键点**:始终使用 `it = vec.erase(it)` 接收返回值,并在未删除时才显式递增迭代器[^5]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值