2010-02-03 52 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),所以对于这个问题没有单一的解决方案,你必须知道你在迭代什么。至少在下一个标准发布和编译器赶上之前。