Unordered_map迭代器失效

时间:2012-04-22 12:55:52

标签: c++ iterator unordered-map

我有这个迭代器循环,

typedef  boost::unordered_map<std::pair<int, int>, NavigationNode> NodesMap;
NodesMap nodes;
for (NodesMap::iterator it= nodes.begin(); it != nodes.end() ; ++it)
{

  if(it->second.type == NavigationNodeType_Walkable)
  {
    ConnectNode(&it->second);
  }

}

ConnectNode函数似乎使迭代器无效。它在NavigationNode中推送新元素并修改NavigationNode的现有成员。

我有两个问题

  • 传递它 - &gt;秒作为指针坏了吗?
  • 迭代这个容器的最佳方法是什么?
谢谢。

修改

会像这样访问容器的元素

   nodes[intpair(x, y)]

在ConnectNode函数中会导致这个问题吗?

EDIT2 是的,确实如此。

为什么?我怎么绕过它?

2 个答案:

答案 0 :(得分:1)

  • 传递它 - &gt;秒作为指针坏吗?

    这取决于指针本身所执行的功能。孤立地看,传递指针没有任何内在错误。

  • 迭代这个容器的最佳方法是什么?

    你使用的方式很好。使用begin()end()进行迭代非常标准。

所以我认为问题必须在ConnectNode,并且很可能你没有迭代器失效问题,而是其他问题。

“会像这样访问容器的元素”

nodes[intpair(x, y)]

这将向地图添加一个新的条目,其中一个键intpair(x,y)不存在,所以是的,这可能会使迭代陷入困境。您可以通过在使用[]运算符访问之前检查该键是否存在该元素来避免这种情况。

答案 1 :(得分:1)

根据您的更新,ConnectNode可以修改您正在迭代的地图。

nodes[intpair(x, y)]

如果地图中尚不存在该键,则会插入新元素。这可能会导致地图重新散列,使所有迭代器无效。

为避免修改地图,您可以使用find()at()find()将通过其返回值指示密钥是否存在,如果密钥不存在,则at()将抛出。

如果您确实需要在ConnectNode期间向地图添加新元素,那么事情就更棘手了。您可以将它们放在一个单独的容器中,然后在循环后将它们添加到nodes