三行代码  ›  专栏  ›  技术社区  ›  clove682

使用[]运算符在无序_图中插入元素时出现分段错误

  •  -2
  • clove682  · 技术社区  · 2 月前

    正如标题所说,当无序的_映射使用[]操作符插入元素时,会出现分段错误,对我来说,最令人困惑的地方是,当我在vec上使用resize()时,会发生此错误,当我使用push_back()时,程序没有问题。我不明白这是什么原因。

    #include<iostream>
    #include<unordered_map>
    #include<vector>
    #include<cstdlib>
    #include<ctime>
    
    using namespace std;
    
    struct Element
    {
      int key;
      vector<int> vec;
      int flag;
    };
    
    class Test
    {
    private:
      unordered_map<int,Element *> map;
    public:
      Element *getElement(int key,int flag)
      {
        Element *element;
        auto temp = map.find(key);
        if(temp==map.end()||flag == temp->second->flag)
        {
          element = new Element();
          element->key = key;
          element->flag = flag;
          if(temp != map.end())
          {
            delete temp->second;
            map.erase(key);
          }
          map[key] = element;
        }
        else
        {
          element = map[key];
        }
        return element;
      }
    };
    
    int main()
    {
      srand((unsigned)time(nullptr));
      Test test;
      for (size_t i = 0; i < 100000; i++)
      {
        /* code */
        int vecSize = rand()%100;
        int key = rand()%5000;
        int flag = rand()%5000;
        Element *element = test.getElement(key,flag);
        if(element->vec.size()==0)
        {
          element->vec.resize(vecSize,0);
        }
        for (size_t i = 0; i < vecSize; i++)
        {
          element->vec[i] = rand()%10000;
        }
      }
      return 0;
    }
    

    输出:

    Program received signal SIGSEGV, Segmentation fault.
    0x000055555555716e in std::__detail::_Hash_node<std::pair<int const, Element*>, false>::_M_next (this=0x8470000046a) at /usr/include/c++/7/bits/hashtable_policy.h:298
    298       { return static_cast<_Hash_node*>(this->_M_nxt); }
    (gdb) bt
    #0  0x000055555555716e in std::__detail::_Hash_node<std::pair<int const, Element*>, false>::_M_next (this=0x8470000046a) at /usr/include/c++/7/bits/hashtable_policy.h:298
    #1  0x000055555555782c in std::_Hashtable<int, std::pair<int const, Element*>, std::allocator<std::pair<int const, Element*> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_rehash_aux (this=0x7fffffffe370, __n=337) at /usr/include/c++/7/bits/hashtable.h:2098
    #2  0x0000555555556ef2 in std::_Hashtable<int, std::pair<int const, Element*>, std::allocator<std::pair<int const, Element*> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_rehash
        (this=0x7fffffffe370, __n=337, __state=@0x7fffffffe220: 167) at /usr/include/c++/7/bits/hashtable.h:2071
    #3  0x00005555555564e0 in std::_Hashtable<int, std::pair<int const, Element*>, std::allocator<std::pair<int const, Element*> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_insert_unique_node (this=0x7fffffffe370, __bkt=88, __code=1424, __node=0x55555577a330) at /usr/include/c++/7/bits/hashtable.h:1718
    #4  0x0000555555555992 in std::__detail::_Map_base<int, std::pair<int const, Element*>, std::allocator<std::pair<int const, Element*> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true>, true>::operator[] (this=0x7fffffffe370, __k=@0x7fffffffe2f4: 1424) at /usr/include/c++/7/bits/hashtable_policy.h:728
    #5  0x00005555555554db in std::unordered_map<int, Element*, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, Element*> > >::operator[] (this=0x7fffffffe370, 
        __k=@0x7fffffffe2f4: 1424) at /usr/include/c++/7/bits/unordered_map.h:973
    #6  0x00005555555551ca in Test::getElement (this=0x7fffffffe370, key=1424, flag=318) at main.cpp:35
    #7  0x0000555555554e23 in main () at main.cpp:56
    
    1 回复  |  直到 2 月前
        1
  •  0
  •   Victor Eijkhout    2 月前

    让我们看看你的主要设计决定:

      unordered_map<int,Element *> map;
    

    您使用的是一个“裸指针”,它应该保留在数据结构 map ,需要引用某个东西,但它不拥有它。你的程序不是这样的:没有其他人拥有 Element 物体。因此,您应该显式存储它们,并返回引用:

    unordered_map<int,Element> map;
    
    Element& getElement(int key,int flag);
    

    正如其他人也指出的那样:你的程序可以更简单,也可以更正确。因为你没有写适当的C++,所以你的生活太难了。

    推荐文章