You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
If you have a destructor that calls erase on a ankerl::unordered_dense::map that is currently being erased from, the code will enter an infinite loop.
As a workaround extract can be used instead of erase to delay the destructor from running until the initial erase finishes.
Expected behavior
Same as std::unordered_map - doesn't freeze and erases correctly.
System:
OS: Windows
Compiler: MSVC
Version: 19.39
Additional context
Callstack:
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::next(unsigned int bucket_idx) Line 852 C++
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::do_erase<`ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase'::`2'::<lambda_1>>(unsigned int bucket_idx, ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase::__l2::<lambda_1> handle_erased_value) Line 1038 C++
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::do_erase_key<int const &,`ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase'::`2'::<lambda_1>>(const int & key, ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase::__l2::<lambda_1> handle_erased_value) Line 1063 C++
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase(const int & key) Line 1683 C++
ConsoleApplication1.exe!`main'::`2'::Foo::~Foo() Line 20 C++
ConsoleApplication1.exe!`main'::`2'::Foo::`scalar deleting destructor'(unsigned int) C++
ConsoleApplication1.exe!std::default_delete<`main'::`2'::Foo>::operator()(main::__l2::Foo * _Ptr) Line 3139 C++
ConsoleApplication1.exe!std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>::~unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>() Line 3251 C++
ConsoleApplication1.exe!std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>::~pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>() C++
ConsoleApplication1.exe!std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>::`scalar deleting destructor'(unsigned int) C++
ConsoleApplication1.exe!std::destroy_at<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>(std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>> * const _Location) Line 326 C++
ConsoleApplication1.exe!std::_Default_allocator_traits<std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>>::destroy<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>(std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>> & __formal, std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>> * const _Ptr) Line 738 C++
ConsoleApplication1.exe!std::vector<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>>::pop_back() Line 1721 C++
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::do_erase<`ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase'::`2'::<lambda_1>>(unsigned int bucket_idx, ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase::__l2::<lambda_1> handle_erased_value) Line 1043 C++
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::do_erase_key<int const &,`ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase'::`2'::<lambda_1>>(const int & key, ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase::__l2::<lambda_1> handle_erased_value) Line 1063 C++
ConsoleApplication1.exe!ankerl::unordered_dense::v4_4_0::detail::table<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>,ankerl::unordered_dense::v4_4_0::hash<int,void>,std::equal_to<int>,std::allocator<std::pair<int,std::unique_ptr<`main'::`2'::Foo,std::default_delete<`main'::`2'::Foo>>>>,ankerl::unordered_dense::v4_4_0::bucket_type::standard,0>::erase(const int & key) Line 1683 C++
ConsoleApplication1.exe!main() Line 30 C++
The text was updated successfully, but these errors were encountered:
I had a look, that's something that I can't support in the map. Note that as far as I can say it is not officially supported by std as well, and it might randomly work or not. It certainly doesn't work with boost maps.
Describe the bug
If you have a destructor that calls
erase
on aankerl::unordered_dense::map
that is currently being erased from, the code will enter an infinite loop.As a workaround
extract
can be used instead oferase
to delay the destructor from running until the initial erase finishes.To Reproduce
Run the following code:
Expected behavior
Same as
std::unordered_map
- doesn't freeze and erases correctly.System:
Additional context
Callstack:
The text was updated successfully, but these errors were encountered: