Opened 8 years ago
Closed 8 years ago
#10469 closed Bugs (fixed)
Erasing from intrusive unordered_multiset with optimize_multikey goes into an infinite loop
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | To Be Determined | Component: | intrusive |
Version: | Boost 1.56.0 | Severity: | Problem |
Keywords: | Cc: |
Description
I create an intrusive unordered_multiset and insert multiple elements with the same key into it. When I try to erase an element through an iterator, like so:
ms.erase(ms.iterator_to(elem));
, the erase function never returns.
I use Microsoft Visual Studio 2010. Ran into this problem with boost 1.51, and verified that it still exists in 1.56. Same code seems to run fine with optimize_multikey<false>. Here's the complete code:
#include <boost/intrusive/unordered_set.hpp> #include <iostream> using namespace boost::intrusive; //------------------------------------------------------------------------ struct MyClass { typedef unordered_set_member_hook<optimize_multikey<true> > MultisetHook; int id_; int key_; MultisetHook byKeyHook_; friend bool operator== (const MyClass &lhs, const MyClass &rhs) { return lhs.key_ == rhs.key_; } friend std::size_t hash_value(const MyClass &v) { return std::size_t(v.key_); } }; //------------------------------------------------------------------------ typedef member_hook< MyClass, MyClass::MultisetHook, &MyClass::byKeyHook_> MyHook; typedef unordered_multiset<MyClass, MyHook> Multiset; //------------------------------------------------------------------------ size_t const NUM_BUCKETS = 32; size_t const NUM_RECS = 10; //------------------------------------------------------------------------ int main(int argc, char* argv[]) { Multiset::bucket_type buckets[NUM_BUCKETS]; Multiset ms(Multiset::bucket_traits(buckets, NUM_BUCKETS)); MyClass recs[NUM_RECS]; for (size_t i = 0; i != NUM_RECS; ++i) { MyClass & rec = recs[i]; rec.id_ = i; rec.key_ = i < 6 ? 123 : 456; ms.insert(rec); } std::cerr << "--- before erase ---\n"; for (auto it = ms.begin(), endIt = ms.end(); it != endIt; ++it) { std::cerr << "rec " << it->id_ << " key=" << it->key_ << std::endl; } { MyClass & rec = recs[4]; std::cerr << "--- erasing rec " << rec.id_ << " ---\n"; // Stuck in the following erase ms.erase(ms.iterator_to(rec)); } std::cerr << "--- after erase ---\n"; for (auto it = ms.begin(), endIt = ms.end(); it != endIt; ++it) { std::cerr << "rec " << it->id_ << " key=" << it->key_ << std::endl; } return 0; }
And here's the output:
--- before erase --- rec 6 key=456 rec 9 key=456 rec 8 key=456 rec 7 key=456 rec 0 key=123 rec 5 key=123 rec 4 key=123 rec 3 key=123 rec 2 key=123 rec 1 key=123 --- erasing rec 4 ---
Note:
See TracTickets
for help on using tickets.
Thanks for the report, there was a bug when inserting elements. Fixed in:
[develop 702ae47] Fixed #10469: Erasing from intrusive unordered_multiset with optimize_multikey goes into an infinite loop