【问题标题】:c++ map/set iterator not dereferencable using .findc++ map/set iterator not dereferencable using .find
【发布时间】:2014-09-23 01:11:21
【问题描述】:

我对使用地图比较陌生,我目前正在使用Debug Assertion Failed Expression: map/set iterator not dereferencable

当我点击重试时,它会将我带到这部分代码:

auto temp = mOpenMap.find(currentNode); temp->second = false;

我认为这与返回地图末尾的 .find(currentNode) 有关,因为它没有找到它,但这里有关的部分是在进行手动调试时,我发现唯一的 Node 在地图确实包含我搜索的currentNode 的确切部分。

我的地图是这样的:

std::map<PathNode*, bool> mOpenMap

乐观地说,我希望它搜索 rowcolumn 以确定它正在查看一个已经搜索过的节点,以便我可以将随附的 boolean 设置为 false。

我想知道的是,地图通常如何搜索对象?或者更好的是,如何使用自定义搜索进行地图搜索?

【问题讨论】:

  • 有时这可能表明您通过值而不是通过引用将映射传递给函数,但在这种情况下看起来不太可能。

标签: c++ map path-finding


【解决方案1】:

在取消引用迭代器之前,您应该检查 std::map::find 是否找到了元素:

auto temp = mOpenMap.find(currentNode);
if (temp != mOpenMap.end())  // check temp is pointing to underneath element of a map
{
    temp->second = false;
}

【讨论】:

  • 这消除了错误,但在消除更多错误之前,我不知道它是否真的成功了(确保路径正常工作)
  • 当您尝试查找 STL 容器时,您需要确保每个迭代器都是有效的。顺便说一句,其他错误是什么?
【解决方案2】:

如果您所做的只是跟踪某些PathNode 或其他的存在,您最好使用std::set

对于自定义搜索,std::mapstd::set 都使用由比较器排序的值集合。在定义映射或集合时,可以将该比较器指定为第二个模板类型。如果省略,则该比较器默认为std::less,它只是将对象与小于运算符operator< 进行比较。如所写,您的地图mOpenMap 正在使用指针的值来执行此比较,这可能不是您想要的。

我建议您声明并定义PathNode::operator<,并将mOpenMap 替换为std::set<PathNode> 类型的成员。这将关闭实际的PathNode 值,而不是指针(在正常情况下可能永远不会发生冲突)。

请记住,您的 PathNode::operator< 应该生成 PathNode 对象的严格排序。这是 std::map 和 std::set 比较器的要求。如果你不遵守这条规则,它的行为会不正常,但它会编译和运行,所以一定要注意这个细节。

【讨论】:

  • 这不是问题的真正答案,应该是评论。
  • 对于可能做我正在做同样事情的其他人来说,答案是一件非常好的事情。很多人只会瞥一眼cmets。
  • 评论太长了。如果不看更多代码,很难说这是否正确有用,但很少需要 std::map<anything, bool> 而不是 std::set<anything> 处理得更简洁。
【解决方案3】:

您应该按照 billz 的说法检查结果。查找失败的最可能原因是您的地图键入PathNode *,这意味着它只会找到具有精确指针匹配的节点。搜索与地图中成员值相同的路径节点将不起作用。

如果您需要地图位于PathNode *,那么您还需要提供predicate 作为地图的第三个参数。需要编写 predicate 来比较两个 PathNode * 参数的成员值。

【讨论】:

    猜你喜欢
    • 2012-11-09
    • 2013-06-25
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2018-04-17
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多