-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maybe it would make sense for the self-insertion/emplacement to work (suggestion) #25
Comments
Hi, Thank you for the suggestion. It's effectively an undefined behaviour. As specified in the documentation, any operation modifying the hash map may invalidate the iterators and references to the objects in the hash map. The I didn't know that I have to see how this can be done as there are two problems:
I have to think a bit if it can be done and how this can be done efficiently and come back to you in a couple of days. For the second point I can just check if the element in the bucket I'm stealing hasn't the same address as the one I want to insert. |
You can see the fix in the link:
So, if you know invalidation is going to happen, construct the element in the stack first, do the invalidation, then move the object from the stack into place. |
Thank you, I checked a bit further the issue and it seems to be effectively possible without too much troubles. I'll be a bit busy the coming week but I'll check to implement the fix when I can find some time. |
Hello, Working a bit on the issue I realized it's not really possible for the following code to work with an open-adressing implementation: int main ()
{
tsl::robin_map<int, std::string> v;
v[0] = "23";
for (int i = 2; i < 3300; ++i)
v[i] = v[0];
} In the loop, the The best that can be done is to make the following code valid by being careful on rehash: int main ()
{
tsl::robin_map<int, std::string> v;
v[0] = "23";
for (int i = 2; i < 3300; ++i)
v.try_emplace(i, v[0]);
} |
Sorry for late response but I do think that |
Currently the following code leads to crash/undefined behavior with
tsl::robin_map
:It happens because we pass the reference to our own element which gets destroyed during reallocation and since construction happens late it leads to the unfortunate results. I understand that this might be a design decision to treat it as UB however I have the following reason for suggesting to fix this:
It works fine with node-based (
std::
) maps.It works with
std::vector
. I can't quote standard paragraph exactly but here's link to the statement from Microsoft of fixing this problem in their implementation https://devblogs.microsoft.com/cppblog/stl-fixes-in-vs-2017-rtm/ (Fixed aliasing bugs
)It actually seems to be much more frequent operation for unordered map rather than for vector, simply copying a past value to the newly created field feels like natural operation in many cases.
A fix seems to be the same as for vector since it is the structure robin map built upon so should not be that hard to implement.
The text was updated successfully, but these errors were encountered: