c++ - unordered_map 元素被删除

标签 c++ c++11 unordered-map

我将 {string, MyStruct} 对象插入到 unordered_map 中,稍后遍历 unordered_map 并选择删除该元素。但是,在删除元素之前,我有一个断言显示 unordered_map 为空。

这是我的插页:

my_umap.insert(std::make_pair(key.toString(), my_struct));

该结构包含一个记录其插入时间的成员。然后我定期检查 map 并删除在 unordered_map 中时间过长的元素:

for(auto it = my_umap.begin(); it != my_umap.end(); ++it){

    MyStruct& myStruct = it->second;
    const bool deleteEntry = myStruct.ts.IsElapsed(std::chrono::seconds(5));

    if(deleteEntry){
        const string& key = it->first;    // Cannot access memory for 'key'
        assert(my_umap.size() >= 1);       // This is failing
        my_umap.erase(key);
    }
}

我在 gdb 中运行代码,断言失败。当我查询 key 的值时,它说

cannot access memory

当我查询 my_umap 的大小时,它说大小为零。

如果 unordered_map 的大小为零,for 循环如何检测元素?没有其他线程访问此容器。我认为 unordered_map::insert() 将对象复制到容器中,所以被删除的原始对象应该无关紧要?

最佳答案

调用 my_umap.erase(...) 后,您的迭代器将失效:

cppreference.com说:

References and iterators to the erased elements are invalidated. Other iterators and references are not invalidated.

这意味着一旦项目被删除,指向它的迭代器就不再有效。

你有几个选择:

1。使用迭代器删除,使用erase()

的返回值

自 C++11 起,通过迭代器删除将返回指向映射中下一项的迭代器。所以你可以使用它来保持你的迭代器有效:

auto it = my_umap.begin();

while (it != my_umap.end()) {

    MyStruct& myStruct = it->second;
    const bool deleteEntry = myStruct.ts.IsElapsed(std::chrono::seconds(5));

    if(deleteEntry){
        assert(my_umap.size() >= 1);
        it = my_umap.erase(it);  // <-- Return value should be a valid iterator.
    }
    else{
        ++it;  // Have to manually increment.
    }
}

2。将迭代器存储在列表对象中并在迭代后删除。

或者,您可以将删除候选对象存储在列表对象中(例如 vector 并在初始迭代后删除它们:

std::vector<MapType::iterator> deleteCandidates;

for(auto it = my_umap.begin(); it != my_umap.end(); ++it){

    MyStruct& myStruct = it->second;
    const bool deleteEntry = myStruct.ts.IsElapsed(std::chrono::seconds(5));

    if(deleteEntry)
        deleteCandidates.push_back(it);
}

for (auto it : deleteCandidates) {
    my_umap.erase(it);
}

至于为什么你的断言失败,你可能遇到了访问无效迭代器的未定义行为,使你的 for 循环相信映射仍然不为空(因为 invalidIterator ! = my_umap.end()).

关于c++ - unordered_map 元素被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38854265/

相关文章:

C++11:参数包扩展计数器

c++ - 引用是如何在内部实现的?

c++ - 如何访问封装在类中的未命名的 "enum class"?

c++ - std::mt19937 是否需要预热?

C++11:迭代时从 std::unordered_map 中删除单个元素是否安全?

c++ - C++ 中 MyType(myVar) 声明的意义何在?

c++ - 当我修改复制构造函数做一些奇怪的事情然后按值将一个对象(属于那个类)传递给一个函数时会发生什么?

C++ unordered_map 防止字符串键的内存重新分配

c++ - 如何将 boost::object_pool 与 std::unique_ptr 一起使用?

c++ - C++:在一个循环中遍历列表和unordered_map