首页 > 解决方案 > map::erase 有时不会从地图中删除条目

问题描述

我现在遇到一个零星的问题,map::erase() 说它有效,但地图有时仍然包含元素。

auto iterator = device_map.begin();  // std::map<std::string,Device*>
size_t nDeleted = 0;
while (iterator != map.end()) {
    Device* device = device_map[iterator->first];
    if (device->done()) {
        device->close();
        cout << "Erasing " << iterator->first << endl;
        nDeleted = device_map.erase(iterator->first);
        delete device;
    }
    ++iterator;
}

每 500 毫秒在 std::thread 中调用一次。我已经通过在循环之前和之后打印地图的内容来测试它,如下所示:

cout << "device_map = ";
for (std::map<string, Device*>::iterator it = device_map.begin(); it != device_map.end(); ++it) {
    cout << it->first << " = " << it->second << "; ";
}
cout << endl;

有时,即使 nDeleted == 1,device_map 的内容在取消映射元素之前和之后是相同的(除了 *device == nullptr 因为删除)。

我还设置了一个断点,并且 device_map.size() 在调用 device_map.erase() 后确实没有改变。

我已经尝试过其他版本的 map::erase,结果相同:

auto iterator = device_map.begin();  // std::map<std::string,Device*>
size_t nDeleted = 0;
while (iterator != map.end()) {
    Device* device = device_map[iterator->first];
    if (device->done()) {
        device->close();
        cout << "Erasing " << iterator->first << endl;
        iterator = device_map.erase(iterator);
        delete device;
    } else {
        ++iterator;
    }
}

有什么我做错了吗?

谢谢,

弗雷德

标签: c++stdmap

解决方案


正如@Jeffrey 建议的那样,问题在于另一个线程在调用 map::erase 时访问了 std::map 对象。添加互斥锁解决了这个问题。


推荐阅读