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

C++ std::map执行erase操作时崩溃,如何修改代码实现防护?

问题根因

你的崩溃本质是跨锁持有STL容器迭代器导致的迭代器失效问题:
你在获取subs_.begin()后立即释放了互斥锁,此时如果其他线程对subs_执行插入、删除操作,你手里持有的迭代器it会直接变成失效的野迭代器。后续进入循环再加锁访问it时,本质是在访问非法内存,才会出现28473456这类异常ID,最终调用erase时触发崩溃。

修复方案

方案1:遍历全程持锁(简单稳妥,优先选择)

如果遍历逻辑耗时不长,直接把迭代器初始化和整个遍历过程放在同一个锁作用域内,全程持有锁避免其他线程修改容器,从根源上避免迭代器失效:

void SubscManag::handleNotif(Notif notif)
{
    std::cout << "Current subscribe size: " << subs_.size();
    // 整个遍历过程持锁,期间其他线程无法修改subs_
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    auto it = subs_.begin();
    while (it != subs_.end())
    {
        if (it->second.hasToBeErased)
        {
            std::cout << "Erase id : " << it->first;
            it = subs_.erase(it);
            continue;
        }
        if (cond)
        {
            // ....
            ++it;
            continue;
        }
        // ....
        ++it;
    }
}

方案2:细粒度锁+批量删除(适合遍历逻辑耗时较长的场景)

如果不想长时间持有锁影响并发性能,可以先收集需要处理/删除的标识,再统一操作,删除前额外校验元素有效性,避免野指针崩溃:

void SubscManag::handleNotif(Notif notif)
{
    std::cout << "Current subscribe size: " << subs_.size();
    std::vector<int> toEraseIds;
    // 第一步:短时间持锁,仅收集需要删除的ID,耗时业务逻辑可拷贝数据后放到锁外执行
    {
        std::lock_guard<std::recursive_mutex> lock(mutex_);
        for (auto& pair : subs_) {
            if (pair.second.hasToBeErased) {
                toEraseIds.push_back(pair.first);
            } else if (cond) {
                // 此处把需要处理的数据拷贝到临时变量,不要在锁内执行耗时操作
                // tempData.push_back(pair.second);
            }
        }
    }

    // 第二步:持锁批量删除,删除前先校验元素是否存在
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    for (int id : toEraseIds) {
        auto it = subs_.find(id);
        // 确认元素存在再删除,避免重复删除或者元素已被其他线程删除的情况
        if (it != subs_.end()) {
            std::cout << "Erase id : " << id;
            subs_.erase(it);
        }
    }

    // 锁外执行耗时的业务逻辑处理
    // processTempData(tempData);
}
额外注意事项
  • 不要跨锁持有任何STL容器的迭代器,只要锁释放,其他线程就可能修改容器导致迭代器失效
  • 递归互斥锁如果没有必须使用的场景,建议换成普通std::mutex,性能更好也能降低死锁风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 15:54:10