擦除嵌套地图中的元素

时间:2015-11-19 23:53:29

标签: c++ dictionary nested erase

我希望能够移除一个元素,但我不知道自己错过了什么。程序崩溃了。

void Movies::removePeliculaAlies(short unsigned year,string title){
    map<string,map<unsigned short, string> >::iterator itAlies=_mapaAlies.begin();
    while(itAlies!=_mapaAlies.end()){
        map<unsigned short,string>::iterator itInterior;
        itInterior=itAlies->second.find(year);
        if(itInterior!=itAlies->second.end()){
            if(title==itInterior->second){
                itAlies->second.erase(itInterior);->>>>>>>>>>>>>NOT WORKING WHY?
            }
            if(itAlies->second.size()==0) _mapaAlies.erase(itAlies->first);
        }
        itAlies++;
    }
}

2 个答案:

答案 0 :(得分:2)

崩溃可能是由以下代码引起的:

    if(itAlies->second.size()==0) _mapaAlies.erase(itAlies->first);
}
itAlies++;

在这里,您正在编辑_mapaAlies,在此之后您即可执行itAlies++;,即使编辑无效了迭代器itAlies

相反,你可以尝试先增加然后删除元素

    if(itAlies->second.size()==0){
        map<string,map<unsigned short, string> >::iterator oldIter = itAlies; // copy the iterator
        ++itAlies;                 // increment the iterator
        _mapaAlies.erase(oldIter); // erase the copy
        continue;                  // skip the incrementing in the end
    }
}
itAlies++;

一般情况下,您应该在循环编辑容器时进行各种编辑,因为编辑可能会使迭代器失效并导致崩溃或可能更糟。

答案 1 :(得分:1)

我在自己的代码中看到过类似的问题。我不认为崩溃与你在地图中有地图的事实有关。我认为问题更可能与您在迭代同一地图时删除地图元素的事实有关。

我在自己的代码中解决了这个问题如下:我遍历地图,如果我擦除任何地图元素,我将引发一个布尔标志并打破我的迭代循环。在循环之后,如果该标志被引发,我将重新开始迭代并重复,直到不再需要擦除为止。这是我的代码:

void serve::reclaim_server_resources()
{
    dPrintf("()");

    bool erased = false;

    for (std::map<int, serve_client>::iterator iter = client_map.begin();
         iter != client_map.end(); ++iter) {
        if (!iter->second.check()) {
            dPrintf("erasing idle client...");
            client_map.erase(iter->first);
            /* stop the loop if we erased any targets */
            erased = true;
            break;
        }
    }

    /* if we erased a target, restart the above by re-calling this function recursively */
    if (erased)
        reclaim_server_resources();
}

如果我从循环中删除break;,代码会崩溃,可能与您的代码相同。

这实际上只是针对您的问题的解决方法的建议。也许可能有更好的解决方案,但至少应该知道类似问题在其他类似情况下会如何表现。

如果你想自己尝试我的解决方法,你可能想要将你的功能分解成两个较小的函数,这样当你通过递归调用new函数重启迭代时,它可以重新启动内部映射的迭代,而不是重新启动整个外部地图。