2

gcc 4.7.2 で SEGV に遭遇しましたunordered_map

その中find()で が呼び出さ_M_find_nodeれ、次に が呼び出され、バケット番号、検索対象のキー、およびハッシュ コード_M_find_before_nodeが渡されます。

では_M_find_before_node、問題のバケット内の最初のノードを検索します。

_BaseNode* __prev_p = _M_buckets[__n];

次に、これに続くノードを取得します。

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

問題はそれ__prev_p->_M_nxtが null であることです。そして_M_equalsそれを逆参照しようとし、セグフォルトを引き起こします。

私は 100% の内部の仕組みについて手がかりがありませんunordered_map- バケットの最初のノードが_M_nxtnull でないことが要件ですか、それともバグですか?

問題のコードは次のとおりです。

  // Find the node whose key compares equal to k in the bucket n. Return nullptr
  // if no node is found.
  template<typename _Key, typename _Value,
       typename _Allocator, typename _ExtractKey, typename _Equal,
       typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
       bool __chc, bool __cit, bool __uk>
    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
            _Equal, _H1, _H2, _Hash, _RehashPolicy,
            __chc, __cit, __uk>::_BaseNode*
    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
           _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    _M_find_before_node(size_type __n, const key_type& __k,
            typename _Hashtable::_Hash_code_type __code) const
    {
      _BaseNode* __prev_p = _M_buckets[__n];
      if (!__prev_p)
    return nullptr;
      _Node* __p = static_cast<_Node*>(__prev_p->_M_nxt); // __p is null here!!
      for (;; __p = __p->_M_next())
    {
      if (this->_M_equals(__k, __code, __p))
        return __prev_p;
      if (!(__p->_M_nxt) || _M_bucket_index(__p->_M_next()) != __n)
        break;
      __prev_p = __p;
    }
      return nullptr;
    }
4

3 に答える 3

3

私は 100% の内部の仕組みについて手がかりがありませんunordered_map- バケットの最初のノードが_M_nxtnull でないことが要件ですか、それともバグですか?

_M_buckets[__n]質問は明らかにGCCの実装に固有のものですが、ifが非nullの場合も非nullである必要があると確信してい_M_buckets[__n]->_M_nxtます。

つまり、バケットが空の場合は 、バケットが空_M_buckets[__n]==nullptrでない場合はバケット_M_buckets[__n]->_M_nxt内の最初のノードです。

でビルドしてみ-D_GLIBCXX_DEBUGて、コードに問題があるかどうかを確認してください。バグがある可能性はありますが、何らかの理由でコンテナーが破損しているか、コンテナーの使用方法が間違っている可能性が高くなります。

于 2013-05-03T09:23:38.360 に答える
2

Unless you have detected an error in the gcc std::unorderd_map implementation, the most likely cause of your error is that you did something like:

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

If that's the case, replace it with

if (it != my_map.end()) {
    do something with *it;
}
于 2013-05-03T09:22:31.083 に答える