【问题标题】:"map/set iterators incompatible" while calling std::map::find调用 std::map::find 时出现“映射/设置迭代器不兼容”
【发布时间】:2012-08-29 21:03:13
【问题描述】:

C++ 0x11(有点。你知道,微软等等……),Visual Studio 2010 SP1,Windows 7 Enterprise。

我有一个函数:

// typedef boost::variant</*stuff*/> value_t;
// typedef unsigned short key_t
// typedef std::map<key_t, value_t> map_t

value_t find(const key_t key, const map_t &map)
{
    const map_t::const_iterator iter(map.find(key));

    // ...More stuff and then return.
}

在 std::map::find 的主体中,有一个迭代器比较,我收到错误消息“map/set iterators incompatible”,如 VC\include\xtree:321 中所定义。这个错误的本质是来自两个不同容器的迭代器被相互比较,但错误来自 在容器自己的 find 函数中!!! 反言之,另一个容器的迭代器可能来自哪里来自。

好的,症状:

  • 线程应用程序。
  • 它只发生在运行时,在实际应用程序的随机压力测试期间。
  • 我们没有看到任何无效或明显的垃圾字段。

我向广大社区提出的问题:

假设这是线程环境中的计时错误,是否可以在此过程的中途更改映射的内部状态,修改模板类_Tree_const_iterator::_Getcont() 的值?我假设在该线程中的查找完成之前,地图已被清除并重新填充到另一个线程中。单凭这一点能行吗?或者如何进行交换或移动操作?

我将追查丢失的互斥锁或其他任何东西,我只是想确保我了解在给定上下文的情况下我可以进入此状态的所有合理手段。

【问题讨论】:

  • 很可能您在执行find 时由于修改了地图而导致了未定义的行为...
  • 我同意这看起来像是在一个线程中更新地图而在第二个线程中使用 find 进行搜索时出现的问题。
  • 它更有可能是一个无效的迭代器而不是“另一个容器的迭代器”,这是由于在find 正在读取它时映射发生变化。如果地图从一个线程更改,而另一个线程访问它,那么几乎任何事情都可能出错。
  • 我在最后一个小时遇到了类似的情况,唯一的区别是所有内容都在主线程中运行。问题出现在 gcc 和 VS2010 上。运行完整的清理和重建后,两个编译器的问题都消失了。

标签: c++ visual-studio-2010 map c++11 iterator


【解决方案1】:

假设这是线程环境中的计时错误

那么所有的赌注都取消了。如果您的代码是线程化的并且不是线程安全的,那么您可能会遇到各种错误。 std::map 不是线程安全的(在修改时您无法访问它),因此您可能会遇到很多错误。

在假设其他错误之前确保您的代码是线程安全的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多