【问题标题】:Unordered_map iterator invalidationUnordered_map 迭代器失效
【发布时间】:2012-04-22 12:55:51
【问题描述】:

我有这个迭代器循环,

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 的现有成员。

我有两个问题

  • 是否将它作为指针传递->秒?
  • 迭代此容器的最佳方法是什么?

谢谢。

编辑:

会像这样访问容器的元素

   nodes[intpair(x, y)]

里面的ConnectNode函数会导致这个问题吗?

edit2 是的。

这是为什么呢?我该如何解决?

【问题讨论】:

  • 你有什么证据表明迭代器失效了?
  • 无序映射的迭代器只有在容器本身被修改时才会失效,无论是通过擦除您拥有迭代器的元素,还是在发生重新散列时。
  • 我怀疑它,当我注释掉 ConnectNode 函数时它工作正常。
  • 太好了,那就把它注释掉吧:-)
  • 如果这不是迭代器失效。你知道什么会导致这种情况吗?

标签: c++ iterator unordered-map


【解决方案1】:
  • 传递它->第二个作为指针不好吗?

    这取决于获取指针本身的函数的作用。单独来看,传递指针本身并没有错。

  • 遍历这个容器的最佳方法是什么?

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

所以我认为问题一定出在ConnectNode,而且很可能您没有迭代器失效问题,而是其他问题。

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

nodes[intpair(x, y)]

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

【讨论】:

  • 在 ConnectNode 函数中访问节点映射导致它。(检查编辑)你知道为什么吗?
  • @mikbal 像这样访问节点会添加新元素,如果它们不存在,所以是的,它可能会搞砸。
  • 好的。我应该先检查它是否存在,然后尝试访问它。谢谢你。就是这样。
【解决方案2】:

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

nodes[intpair(x, y)]

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

为避免修改地图,您可以使用find()at()find() 会通过它的返回值来表明key是否存在,如果key不存在,at()会抛出。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-30
    • 2023-01-13
    • 1970-01-01
    • 2015-07-31
    • 2011-04-14
    • 1970-01-01
    • 2015-01-10
    • 2014-06-30
    相关资源
    最近更新 更多