Search code examples
c++11dictionaryboost-multi-index

boost::multi_index_container erase function rehases?


I have the following problem: I have defined a boost::multi_index_container, here a simplified definition which hashes a TYPE by a member function pointer &TYPE::m_id where m_id is an integral type

boost::multi_index::multi_index_container<
    TYPE * ,
    boost::multi_index::indexed_by<
        boost::multi_index::hashed_unique<
            boost::multi_index::tag<by_hashed_id>,
            boost::multi_index::member<TYPE, const TYPE, &TYPE::m_id>
        >
    >
> map;

When I delete an object in the following way:

hashMap = map.index.get<by_hashed_id>()
it = hashMap.find(30);
delete *it;          /// Delete the underlying pointer
hashMap.erase(it);  /// Delete in the map (segfault if the map is rehashed (?))

This code seems to crash when ever erase tries to rehash the map, Does somebody know if this is general behavior, that an erase function might rehash before removing the pointer, which will result in a segfault because the pointer has been deleted already. (Of course the fix is: Move the delete below the erase which is anyway more appropriate!)

I got the following last trace after the segmentation fault.

Last Stack Trace Output:

 [a9203:03910] Signal: Segmentation fault (11)
121 [a9203:03910] Signal code: Address not mapped (1)
122 [a9203:03910] Failing at address: (nil)
123 [a9203:03910] [ 0] /lib64/libc.so.6() [0x36846329a0]
124 [a9203:03910] [ 1] /lib64/libc.so.6() [0x368468e312]
125 [a9203:03910] [ 2] /program( ZNSt10_HashtableIjSt4pairIKjN15BodyProcessInfo5FlagsEESaIS4_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS6_18_Mod    _range_hashingENS6_20_Default_ranged_hashENS6_20_Prime_rehash_policyENS6_17_Hashtable_traitsILb0ELb0ELb1EEEE5clearEv+0x3f)

Solution

  • To answer the question in your subject line: ordered indices, like the one you're using in the code shown, don't hash/rehash ever because they're not hash-based. Hashed indices (which you're not using here, seemingly) don't rehash on erase. The symbols you show on the stack trace look totally alien to Boost.MultiIndex.