我希望能够移除一个元素,但我不知道自己错过了什么。程序崩溃了。
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++;
}
}
答案 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函数重启迭代时,它可以重新启动内部映射的迭代,而不是重新启动整个外部地图。