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

C++ list去重函数触发Segmentation Fault问题求助

解决你的Segmentation Fault段错误问题

我一眼就看出你代码里的问题了——是迭代器的处理逻辑出错导致的段错误,咱们一步步拆解:

首先看你处理重复元素的这段代码:

if (!res.second) {
    next = ++iter;
    _list.erase(iter);
    iter = next;
    continue;
}

这里的核心错误是:你先把iter递增到下一个元素,然后去erase这个已经移动后的iter。这会导致两个问题:

  • 你根本没删除掉那个重复的元素(你本来要删的是原来iter指向的元素);
  • std::list::erase会让被删除的迭代器失效,而你此时的iter和next是同一个对象(因为next = ++iter是把递增后的iter赋值给next),所以iter变成了失效的迭代器,后续循环中使用它必然触发段错误。

正确的修复方式

有几种简洁且安全的写法,推荐按复杂度从低到高选择:

写法1:利用erase的返回值(C++11及以上)

std::list::erase在C++11之后会返回被删除元素的下一个有效迭代器,所以我们可以直接用它来更新iter,完全不需要额外的next变量:

void RemoveDuplicates(list<int>& _list) {
    set<int> uniqueElements;
    auto iter = _list.begin();
    while (iter != _list.end()) {
        auto res = uniqueElements.insert(*iter);
        if (!res.second) {
            // erase返回下一个有效迭代器,直接赋值给iter
            iter = _list.erase(iter);
        } else {
            ++iter;
        }
    }
}

写法2:提前保存下一个迭代器(兼容C++03)

如果需要兼容旧标准,我们可以先保存当前iter的下一个位置,再删除当前元素,最后把iter切换到保存的位置:

void RemoveDuplicates(list<int>& _list) {
    set<int> uniqueElements;
    list<int>::iterator iter = _list.begin();
    list<int>::iterator next;
    pair<set<int>::iterator, bool> res;
    while (iter != _list.end()) {
        res = uniqueElements.insert(*iter);
        if (!res.second) {
            next = next(iter); // 提前获取下一个迭代器
            _list.erase(iter);
            iter = next;
        } else {
            ++iter;
        }
    }
}

写法3:利用iter++的特性(简洁版)

iter++会先返回当前迭代器的副本(用于erase),再把iter移动到下一个位置,这样也能避免失效问题:

if (!res.second) {
    // erase的是递增前的iter,此时iter已经指向了下一个元素
    _list.erase(iter++);
} else {
    ++iter;
}

额外优化建议

如果你的项目使用C++11及以上标准,用auto替代冗长的迭代器声明,代码会更简洁易读,就像写法1里那样。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:46:16