C++ gcc中的SEGV';s std::无序_图

C++ gcc中的SEGV';s std::无序_图,c++,gcc,c++11,unordered-map,C++,Gcc,C++11,Unordered Map,我在gcc 4.7.2的unordered_map 在find()中,它调用\u mu find\u node,该节点依次调用\u mu find\u before\u node,传入桶号、我们正在搜索的键和散列码 在\u M\u find\u before\u node中,它查找相关bucket中的第一个节点: _BaseNode* __prev_p = _M_buckets[__n]; 然后获取以下节点: _Node* __p = static_cast<_Node*>(__p

我在gcc 4.7.2的
unordered_map

find()
中,它调用
\u mu find\u node
,该节点依次调用
\u mu find\u before\u node
,传入桶号、我们正在搜索的散列码

\u M\u find\u before\u node
中,它查找相关bucket中的第一个节点:

_BaseNode* __prev_p = _M_buckets[__n];
然后获取以下节点:

_Node* __p = static_cast<_Node*>(__prev_p->_M_nxt);

除非您在gcc
std::unorderd_map
实现中检测到错误,否则最有可能的错误原因是您执行了以下操作:

std::unorderd_map<MyKey, MyValue> my_map;
auto it = my_map.find(some_key); // if some_key was not found, it == my_map.end()
do something with *it;           // kaboom! derefence of past-the-end iterator
我不是100%了解无序映射的内部工作原理-是要求bucket的
\u nxt
中的第一个节点非空,还是这是一个bug

这个问题显然是针对GCC的实现的,但我非常确定,如果
\u m_bucket[\uu n]
是非空的,那么
\u m_bucket[\uu n]->\u m_nxt
也应该是非空的

i、 e.如果bucket为空,则
\u M_bucket[\u n]==nullptr
,如果bucket为非空,则
\u M_bucket[\u n]->\u M_nxt
是bucket中的第一个节点


试着用
-D_GLIBCXX_DEBUG
构建,看看它是否识别出代码中的问题,可能存在错误,但更有可能是您以某种方式损坏了容器或使用了错误的容器。

这个问题现在已经很老了,但我最近也遇到了同样的问题,下面是如何重现它的示例代码

#include <chrono>
#include <iostream>
#include <thread>
#include <unordered_map>

int main()
{
  std::unordered_map< std::string, int > m_Map{};

   m_Map.insert(std::make_pair("a", 0x61));
   auto count{1000u};

   auto t_remove = std::thread([&m_Map, &count]() {

      while (1)
      {
         m_Map.erase("a");
         std::this_thread::sleep_for(std::chrono::nanoseconds(count));
         if(count > 10)
         {
            count-=10;
         }
         else
         {
             count = 1000u;
         }
         m_Map.insert(std::make_pair("a", 0x61));
      }
   });

   while (1)
   {
      auto it = m_Map.find("a");

      if (it != m_Map.end())
      {
         std::cerr << "Map has a " << it->first << " = " << it->second << "\n";
      }
      else
      {
         std::cerr << "Map does not have a \"a\"\n";
      }
   }

   t_remove.join();
   return 0;
}
#包括
#包括
#包括
#包括
int main()
{
无序映射m\u映射{};
m_Map.insert(std::make_pair(“a”,0x61));
自动计数{1000u};
自动t_remove=std::thread([&m_映射,&count](){
而(1)
{
m_地图删除(“a”);
std::this_线程::sleep_for(std::chrono::纳秒(计数));
如果(计数>10)
{
计数-=10;
}
其他的
{
计数=1000u;
}
m_Map.insert(std::make_pair(“a”,0x61));
}
});
而(1)
{
自动it=m_Map.find(“a”);
if(it!=m_Map.end())
{

std::cerr为什么不显示触发此错误的代码?如果代码正确,您应该提交错误报告。如果不正确,您的问题就会得到解决:)就个人而言,我会首先在我自己的代码中查找错误。您有自己的代码片段复制此错误吗?不能在简单的示例中重新编写-我正在尝试!:/这是我的错误ry整洁,确实应该被标记为正确答案。@HubertLiberacki整洁程度如何?因为两个线程处于数据竞争中。应该有同步访问共享映射。此代码只是一个明显的错误,任何事情都可能发生。
if (it != my_map.end()) {
    do something with *it;
}
#include <chrono>
#include <iostream>
#include <thread>
#include <unordered_map>

int main()
{
  std::unordered_map< std::string, int > m_Map{};

   m_Map.insert(std::make_pair("a", 0x61));
   auto count{1000u};

   auto t_remove = std::thread([&m_Map, &count]() {

      while (1)
      {
         m_Map.erase("a");
         std::this_thread::sleep_for(std::chrono::nanoseconds(count));
         if(count > 10)
         {
            count-=10;
         }
         else
         {
             count = 1000u;
         }
         m_Map.insert(std::make_pair("a", 0x61));
      }
   });

   while (1)
   {
      auto it = m_Map.find("a");

      if (it != m_Map.end())
      {
         std::cerr << "Map has a " << it->first << " = " << it->second << "\n";
      }
      else
      {
         std::cerr << "Map does not have a \"a\"\n";
      }
   }

   t_remove.join();
   return 0;
}
    Thread 1 "find_stress_tes" received signal SIGSEGV, Segmentation fault.
0x000000000040505b in std::__detail::_Equal_helper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, unsigned long, true>::_S_equals (__eq=..., __extract=..., __k="a", __c=4993892634952068459, __n=0x0)
    at /usr/include/c++/5/bits/hashtable_policy.h:1322
1322        { return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); }
(gdb) bt
#0  0x000000000040505b in std::__detail::_Equal_helper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, unsigned long, true>::_S_equals (__eq=..., __extract=..., __k="a", __c=4993892634952068459, __n=0x0)
    at /usr/include/c++/5/bits/hashtable_policy.h:1322
#1  0x0000000000404b2a in std::__detail::_Hashtable_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, false, true> >::_M_equals (this=0x7fffffffdd40, __k="a", 
    __c=4993892634952068459, __n=0x0) at /usr/include/c++/5/bits/hashtable_policy.h:1704
#2  0x00000000004044ef in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_before_node (this=0x7fffffffdd40, __n=1, 
    __k="a", __code=4993892634952068459) at /usr/include/c++/5/bits/hashtable.h:1433
#3  0x0000000000403e50 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_node (this=0x7fffffffdd40, __bkt=1, __key="a", 
    __c=4993892634952068459) at /usr/include/c++/5/bits/hashtable.h:632
#4  0x000000000040392b in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::find (this=0x7fffffffdd40, __k="a")
    at /usr/include/c++/5/bits/hashtable.h:1307
#5  0x0000000000403675 in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >::find (this=0x7fffffffdd40, 
    __x="a") at /usr/include/c++/5/bits/unordered_map.h:615
#6  0x000000000040184b in main () at ../find_stress_test/main.cpp:40