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
。这不仅仅是线程更改对象,甚至读卡器线程也需要它。