martinus / robin-hood-hashing

Fast & memory efficient hashtable based on robin hood hashing for C++11/14/17/20
https://gitter.im/martinus/robin-hood-hashing
MIT License
1.5k stars 142 forks source link

My problem with robin_hood::erase #154

Closed gian-master closed 2 years ago

gian-master commented 2 years ago

hello, I need some help. I have a program like this:

robin_hood::unordered_map<int, int> kk; int a = new int; int b = new int; int c = new int; kk[a] = 1; kk[b] = 1; kk[c] = 1; for(auto iter= kk.begin(); iter != kk.end();) { if(iter->second == 1) { kk.erase(iter++); }else{ iter++; } } cout<<"map size:"<<kk.size(); delete a; delete b; delete c;

I run it ten times, and get output like this: map size:0 map size:0 map size:0 map size:0 map size:0 map size:0 map size:1 map size:0 map size:0 map size:0

obviously, the output is not always 0, is that means the erase func is not support like this?

slavenf commented 2 years ago

Hello.

Please use propper formatting when pasting source code. While writing message, select code and click on toolbar button Add Code or press CTRL+E.

Presented "problem" is not robin hood related. Also the program is incorrect. I recommend reading more about std::unordered_map. At this page is an example how correctly remove elements while iterating the container: https://en.cppreference.com/w/cpp/container/unordered_map/erase That is idomatic way to remove elements while iterating the container (any container, not only unordered map).

slavenf commented 2 years ago

Also consider using non-member function std::erase_if which is available since C++20: https://en.cppreference.com/w/cpp/container/unordered_map/erase_if This function is overloaded for all standard containers.

martinus commented 2 years ago

iterators are not stable, so you must not do kk.erase(iter++);.

gian-master commented 2 years ago

Thanks very much,it looks like I've been doing it the wrong way before, I've learned a lot