C++ 空无序映射上的find()是否会导致访问冲突?

C++ 空无序映射上的find()是否会导致访问冲突?,c++,stl,access-violation,unordered-map,C++,Stl,Access Violation,Unordered Map,我正在调查一个转储,它是由访问冲突引起的。 在特定的代码行上,有以下行: if (internal_map.find(uiElemKey) == internal_map.end() || internal_map[uiElemKey].find(m_iPID) == internal_map[uiElemKey].end() || internal_map[uiElemKey][m_iPID].find(idx) == internal_map[uiElemKey][m_i

我正在调查一个转储,它是由访问冲突引起的。
在特定的代码行上,有以下行:

if (internal_map.find(uiElemKey) == internal_map.end() || 
    internal_map[uiElemKey].find(m_iPID) == internal_map[uiElemKey].end() || 
    internal_map[uiElemKey][m_iPID].find(idx) == internal_map[uiElemKey][m_iPID].end()) {
在watch窗口中,我可以看到
internal\u map
中的条目数量等于0

我认为,访问违规可能是由以下原因造成的:

  • 由于映射中没有条目,因此
    find()
    方法生成异常
  • 由于映射中没有条目,
    end()
    方法生成异常
  • find()
    方法和
    end()
    方法工作正常,但会给出不同的结果,这会导致以下情况,即发生访问冲突
  • 我认为使用以下条件可以避免访问冲突:

    if (internal_map.size() == 0                                              ||
        internal_map.find(uiElemKey) == internal_map.end()                    || 
        internal_map[uiElemKey].find(m_iPID) == internal_map[uiElemKey].end() || 
        internal_map[uiElemKey][m_iPID].find(idx) == internal_map[uiElemKey][m_iPID].end()) {
    
    有人能确认这是正确的,并解释哪个原因是正确的吗?
    提前谢谢


    请注意:我正在进行转储分析,几乎不可能重现所提到的问题,因此尝试看看会发生什么是不可能的。

    假设在执行
    find()
    时,无序映射没有被其他线程修改,那么
    find()
    结束的可能性是微乎其微的()
    将引发异常或崩溃。它们的行为是为空容器定义的。因此,无法通过调用它们来损坏映射。因此,对
    size()
    的测试是多余的。

    假设在
    find()时未被其他线程修改无序映射
    正在执行,则
    find()
    end()
    不可能引发异常或崩溃。它们的行为是为空容器定义的。因此,无法通过调用它们来损坏映射。因此,对
    size()
    的测试是多余的

    由于映射中没有条目,find()方法生成 例外情况

    否,如果您的程序有效(前面某个地方没有UB),则方法将返回结束迭代器,该迭代器等于在同一行代码中由
    end()
    返回的迭代器

    由于映射中没有条目,find()方法生成 例外情况



    否,如果您的程序有效(之前没有UB),则方法将返回结束迭代器,该迭代器等于
    end()返回的迭代器
    在同一行代码中。

    在空映射上调用
    find
    时没有例外。我怀疑您的映射在调用之前已损坏。顺便说一句,通过使用
    find
    返回的迭代器,您可以避免重复查找。查看其他内部成员可能会给出指示。如果映射是
    空的
    ,您能否生成完整的
    5
    复制错误的行示例程序?如果您有多个线程,您应该保护您的数据(
    mutex
    )通过可能同时写入和读取同一变量来避免UB。在空映射上调用
    find
    时没有异常。我怀疑您的映射在调用之前已损坏。顺便说一句,通过使用
    find
    返回的迭代器,您可以避免重复查找。查看其他内部成员可能会给出指示。如果映射是
    >empty
    你能生成一个完整的
    5
    行示例程序来重现错误吗?如果你有多个线程,你应该保护你的数据(
    mutex
    ),通过可能同时写入和读取同一个变量来避免UB。这也是我的想法:启动
    find()
    end())
    不会导致访问冲突。但如果两种方法给出不同的结果,则会访问映射(
    内部映射[uiElemKey]
    ),我担心这可能会导致访问冲突。您认为这可能吗?@Dominique在访问
    内部映射[uiElemKey]之前
    您已经检查了
    uiElemKey
    是否存在。我看不出它们产生访问冲突的任何原因。@Dominique还定义了
    &
    |
    运算符的求值顺序。@Dominique是的,它们对于空容器也是相等的。只要没有键,它就会返回
    end()
    。容器是否为空并不重要。@Dominique:使对象可以从多个线程安全访问的唯一解决方案是
    std::mutex
    。这不仅仅是线程更改对象,甚至读卡器线程都需要它。这也是我的想法:启动
    find()
    end()
    不会导致访问冲突。但如果两种方法给出不同的结果,则会访问映射(
    内部映射[uiElemKey]
    ),我担心这可能会导致访问冲突。您认为这可能吗?@Dominique在访问
    内部映射[uiElemKey]之前
    您已经检查了
    uiElemKey
    是否存在。我看不出它们产生访问冲突的任何原因。@Dominique还定义了
    &
    |
    运算符的求值顺序。@Dominique是的,它们对于空容器也是相等的。只要没有键,它就会返回
    end()
    。容器是否为空并不重要。@Dominique:使对象可以从多个线程安全访问的唯一解决方案是
    std::mutex
    。这不仅仅是线程更改对象,甚至读卡器线程也需要它。