我有以下问题:
我已经定义了一个boost :: multi_index_container,这里是一个简化的定义,它通过成员函数指针TYPE
散列&TYPE::m_id
,其中m_id
是一个整数类型
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;
当我以下列方式删除对象时:
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 (?))
当擦除尝试重新映射地图时,此代码似乎崩溃,
有人知道这是否是一般行为,erase
函数可能在删除指针之前重新散列,这将导致段错误,因为指针已被删除。
(当然修复方法是:将delete
移到erase
以下,这更合适!)
在分段错误后我得到了以下最后一条跟踪。
最后一次堆栈跟踪输出:
[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)
答案 0 :(得分:1)
要回答主题行中的问题:有序索引(如您在所示代码中使用的索引)不会散列/重新散列,因为它们不是基于散列的。散列指数(你似乎没有在这里使用,似乎)不会在erase
上重新散列。您在堆栈跟踪中显示的符号看起来与Boost.MultiIndex完全不同。
答案 1 :(得分:0)
检查是否已定义BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING宏。使用此宏容器验证内部完整性并尝试访问已删除的对象。顺便说一句,有序索引不能基于散列,但是在擦除后确实需要重新平衡的某种树,但通常没有理由访问被删除的元素。