You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ list删除重复元素触发段错误的问题排查

C++ list删除重复元素触发段错误问题解析

核心错误原因

  • 对std::list执行erase()操作后,指向被删除元素的迭代器会直接失效,你代码中调用v3.erase(itip)后,itip已经是无效迭代器,外层循环本轮结束时执行itip++属于对无效迭代器做自增操作,直接访问非法内存,触发段错误。
  • 你代码中删除it后直接执行了内层break,没有触发it++,所以没有暴露it的失效问题,但itip的失效是必现问题。

注意:常见认知误区:list是链表结构,erase操作不会导致迭代器失效。该认知仅适用于指向未被删除节点的迭代器,指向被删除节点本身的迭代器一定会失效,不可继续访问或做自增/自减操作。

修复方案

方案1:基于erase返回值适配你的双重循环逻辑

std::list::erase执行完成后会返回指向被删除元素下一个位置的有效迭代器,你可以用返回值更新迭代器,避免操作失效迭代器:

int main()
{
        vector<pair<int,int>> v1 = {make_pair(1,2),make_pair(3,4)};
        vector<pair<int,int>> v2 = {make_pair(2,3),make_pair(5,6)};
        list<int>v3;
        list<int>::iterator it;
        list<int>::iterator itip;
        vector<pair<int,int>> v4;
        int count = 0;

        for (auto &i :v1)
        {
                v3.push_back(i.first);
                v3.push_back(i.second);
        }
        for (auto &i :v2)
        {
                v3.push_back(i.first);
                v3.push_back(i.second);
        }
        // 修正迭代器自增逻辑:仅未触发删除时才手动自增
        for (itip=v3.begin(); itip != v3.end(); )
        {
                bool has_erased = false;
                for (it = v3.begin() ; it != v3.end(); )
                {
                        if (*itip == *it)
                        {
                                if (itip != it )
                                {
                                   it = v3.erase(it);
                                   itip = v3.erase(itip);
                                   cout<<"List After erased"<<endl;
                                   for (auto &i : v3)
                                   {
                                        cout<<i<<"\t";
                                   }
                                   cout<<"\nList After erased"<<endl;
                                   has_erased = true;
                                   break;
                                }
                        }
                        if (!has_erased) {
                                ++it;
                        }
                }
                if (!has_erased) {
                        ++itip;
                }
        }
        cout<<endl;
        for (auto &i : v3)
        {
                cout<<i<<"\t";
        }

        return 0;
}

方案2:更高效的去重实现(推荐)

如果需求是删除所有出现过多次的元素,不需要嵌套循环,用哈希表统计元素出现次数后单次遍历删除即可,时间复杂度更低:

// 统计每个元素出现次数
unordered_map<int, int> num_cnt;
for (auto num : v3) {
    num_cnt[num]++;
}
// 遍历删除出现次数大于1的元素
for (auto it = v3.begin(); it != v3.end(); ) {
    if (num_cnt[*it] > 1) {
        it = v3.erase(it);
    } else {
        ++it;
    }
}

内容的提问来源于stack exchange,提问作者Nitesh Prabhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 12:24:06