2010-02-03 55 views
0

我有一個圖是這樣的:更新地圖值

map<prmNode,vector<prmEdge>,prmNodeComparator> nodo2archi; 

當我有更新的值(矢量),我把鑰匙,他的價值,我更新值的向量,我刪除舊的鍵和值,然後我插入密鑰和新的矢量。該代碼是這樣的:

bool prmPlanner::insert_edgemap(int from,int to) { 

    prmEdge e; 
    e.setFrom(from); 
    e.setTo(to); 

    map<prmNode,vector<prmEdge> >::iterator it; 

    for (it=nodo2archi.begin(); it!=nodo2archi.end(); it++){ 
     vector<prmEdge> appo; 
     prmNode n; 
     n=(*it).first; 
     int indice=n.getIndex(); 

     if (indice==f || indice==t){ 
      appo.clear(); 
      vector<prmEdge> incArchi; 
      incArchi=(*it).second; 
      appo=(incArchi); 

      appo.push_back(e); 

      nodo2archi.erase(it); 
      nodo2archi.insert(make_pair(n,appo)); 
     } 

    } 
return true; 
} 

的問題是,在第40-50迭代iterations諸事WEEL和地圖更新好,同時與更多的迭代它去有時段錯誤,有時會在一個無限閒置。我不知道爲什麼。有人可以幫助我嗎? 非常感謝。

回答

2

你只是試圖將數據追加到一些映射的向量?在這種情況下,您不需要擦除和插入任何東西:

for (MapType::iterator it = map.begin(); it != map.end(); ++it) { 
    if (some_condition) { 
     it->second.push_back(some_value); 
    } 
} 
+0

非常感謝,我用這種方式解決了我的問題!!!!!! Thankssssssss – livio8495 2010-02-03 14:17:00

1

在迭代它時修改集合。

0

您在遍歷地圖時正在擦除節點。這是要求麻煩:)

4

您正在遍歷nodo2archi,並在同一時間通過做nodo2archi.erase(it);nodo2archi.insert(make_pair(n,appo));更改其大小。如果你這樣做,你的迭代器可能會失效,你的it++可能會崩潰。

0

迭代時,您不能修改集合本身。 C++將允許它,但它仍然導致未定義的行爲。像Java這樣的其他語言具有快速迭代器,當集合被修改時它立即中斷。

+0

如果正確完成,則不會。對於序列容器,「擦除」操作會將有效的迭代器返回到容器中的下一個元素。這在聯合容器中是缺乏的,但會在下一個標準中加入。什麼是UB在你剛纔刪除的同一個迭代器上運行,以及在容器更改之前獲取的任何迭代器中的某些容器。 – 2010-02-03 12:45:48

2

問題是,在刪除迭代器it之後,您試圖對它執行操作(增量),這是未定義的行爲。一些答案指出,在迭代容器時修改容器是UB,但這不是真的,但是您必須知道迭代器何時失效。

對於序列容器中,erase操作將返回一個新的有效迭代器在容器中的下一個元素,所以這將是從這樣的容器擦除的正確和慣用的方式:

for (SequenceContainer::iterator it = c.begin(); it != c.end();) 
    // note: no iterator increment here 
    // note: no caching of the end iterator 
{ 
    if (condition(*it)) { 
     it = c.erase(it); 
    } else { 
     ++it; 
    } 
} 

但可悲的是的是,在目前的標準,關聯容器erase不返回一個迭代器(這是固定的,在新標準草案),所以你必須手動假的

for (AssociativeContainer::iterator it = c.begin(); it != c.end();) 
    // again, no increment in the loop and no caching of the end iterator 
{ 
    if (condition(*it)) { 
     AssociativeContainer::iterator del = it++; // increment while still valid 
     c.erase(del);        // erase previous position 
    } else { 
     ++it; 
    } 
} 

而且更可悲的是,SE cond方法對於關聯容器是正確的,對某些序列容器無效(特別是std :: vector),所以對於這個問題沒有單一的解決方案,你必須知道你在迭代什麼。至少在下一個標準發佈和編譯器趕上之前。