迭代地图和擦除元素

时间:2017-03-15 19:54:21

标签: c++ c++11 std

我有一个全局变量map和一个遍历此map元素的函数,例如:

void printMap(){
    for ( auto it = MyMap.begin(); it != MyMap.end(); ++it  ){
        std::cout << it->second;
    }
}

工作正常。

我想在打印元素后为函数添加一个功能,它应该从map中删除,如下所示:

void printMap(){
    for ( auto it = MyMap.begin(); it != MyMap.end(); ++it  ){
        std::cout << it->second;
        MyMap.erase(it);
    }
}

然而,通过添加擦除行,我得到了这种类型的异常错误:

  

线程2:EXC_BAD_ACCESS(代码= 1,地址= 0x20000002)

我尝试了另一种方式:

void myFunction(){
    printMap(); 
    MyMap.clear();
}

但我也得到了同样的例外

  

线程2:EXC_BAD_ACCESS(代码= 1,地址= 0x0)

据我所知,当我们引用不存在的内存位置时会发生这种异常。但是我知道它存在,因为迭代器得到了它的价值而且它被打印了。即便如此,我还是使用了第二种方法,以防我没有提到不存在的内存位置,但我仍然得到了异常。

那么如何迭代元素打印结果然后擦除呢?

UPDATE1
按照以下建议和链接主题,我将我的功能改为:

void printMap(){
    bool i = true;
    for (auto it = MyMap.cbegin(), next_it = MyMap.cbegin(); it != MyMap.cend(); it = next_it)
    {
        cout << it->second;
        next_it = it; ++next_it;
        if (i) {
            MyMap.erase(it);
        }

    }
}

我也试过这个https://stackoverflow.com/a/42820005/7631183https://stackoverflow.com/a/42819986/7631183

问题仍然是已解决,而且我收到同样的错误




UPDATE2
我在不同的机器上运行相同的确切代码,它工作正常。我仍然不知道是什么原因,所以我会按照std::map对第一个问题的评论中的建议进行猜测。

P.S。第一台机器是mac,第二台机器是Linux

2 个答案:

答案 0 :(得分:2)

当您从地图中删除元素时,您已使循环中使用的迭代器无效,从而导致错误。由于这个原因,erase方法返回一个迭代器。

for( auto it = MyMap.begin(); it != MyMap.end(); )
{
    std::cout << it->second;
    it = MyMap.erase(it);
}

这确实是一个重复的问题。你只是不太了解它,看它是重复的。我希望解决迭代器无效的解释有助于清除它。

答案 1 :(得分:0)

在C ++ 11及更高版本中,std:map::erase()会向正在删除的元素后面的元素返回iterator。由于您使用的是auto,因此您使用的是C ++ 11或更高版本,因此在循环浏览std::map时可以使用新的迭代器,例如:

void printMap(){
    auto it = MyMap.cbegin();
    while (it != MyMap.cend()) {
        std::cout << it->second;
        it = MyMap.erase(it);
    }
}

此外,由于您使用的是C ++ 11,因此可以使用range-for循环简化您的第一个打印功能:

void printMap(){
    for ( auto &it: MyMap ){
        std::cout << it.second;
    }
}