-
Notifications
You must be signed in to change notification settings - Fork 185
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
a bug in emplace_new_key() at line 824 flat_hash_map.hpp #23
Comments
It's a bit weird, but it's not a bug because the container re-allocates right after the swap. So yes, in your step 4 the invariants of the container are violated, but that's fine because step 5 is "grow the container and throw all the old memory away" and that restores all the invariants. Now you might have a point though if the allocator throws when the container tries to grow. In that case that code might leave things in the wrong order. It's an interesting case. Not at all easy to handle since at this point a lot of modifications could have already happened. The only thing I can think of doing would be to put a try/catch around the grow call like this: where the function rebuild_entire_container_using_current_memory() would have to be written. It would be pretty slow, but it would only trigger if you run out of memory... I'll have to think about it for a while. The container is not great about handling exceptions, but I do try to handle the case of the allocator throwing and of the object throwing when it's first being created. So I should handle this one... |
@skarupke , Thanks for your replay. Yes, this problem only happens if grow() throws exception. If we record element's original position before doing swap(), so we could restore container's state before execute grow(), and then there is no need to catch exception of grows() because the container keep it's original state. And i think the record does not affect performance because max_lookups is small. |
I have learned your code, and is there a bug in emplace_new_key() at line 824 flat_hash_map.hpp? I'm not sure, pls help to check.
i think the logic of emplace_new_key(int8_t distance_from_desired, EntryPointer current_entry, Key && key, Args &&... args) is to put args to current_entry and find a new bucket for current_entry->value. At line 861, you swap to_insert with result.current->value, code as below:
if (distance_from_desired == max_lookups)
{
swap(to_insert, result.current->value);
grow();
return emplace(std::move(to_insert));
}
may be logic is wrong in following case. Given there are 7 buckets, the content of each bucket as below:
Given param 'current_entry' of emplace_new_key() is point to bucket1, to_insert value is X, and max_lookups is 4. so the code logic is
The text was updated successfully, but these errors were encountered: