These two pieces of code cause issues when the flat_hash_map is used across modules (e.g. being shared between a DLL and the executable, which is a common use case for me):
static sherwood_v3_entry * empty_default_table()
{
static sherwood_v3_entry result[min_lookups] = { {}, {}, {}, {special_end_value} };
return result;
}
void deallocate_data(EntryPointer begin, size_t num_slots_minus_one, int8_t max_lookups)
{
if (begin != Entry::empty_default_table())
{
AllocatorTraits::deallocate(*this, begin, num_slots_minus_one + max_lookups + 1);
}
}
This is because each module will have its own static empty default table, which will cause an issue with deallocation, corrupting the heap.
I assume there are other pathological cases, e.g. two threads could initialize that static at the same time, resulting in two hashtables with different defaults and eventually leading to a heap corruption.
I have successfully worked around the issue by tagging the first sherwood_v3_entry with a flag indicating its the default table, and checking for that instead, however this will cost one byte if T has alignment of 1 byte (otherwise it should occupy the padding space anyway). There might be a better solution, but I'm not familiar enough with the code to find it!
Here's a link to my changes on my own repo if they're of any use.
These two pieces of code cause issues when the flat_hash_map is used across modules (e.g. being shared between a DLL and the executable, which is a common use case for me):
This is because each module will have its own static empty default table, which will cause an issue with deallocation, corrupting the heap.
I assume there are other pathological cases, e.g. two threads could initialize that static at the same time, resulting in two hashtables with different defaults and eventually leading to a heap corruption.
I have successfully worked around the issue by tagging the first sherwood_v3_entry with a flag indicating its the default table, and checking for that instead, however this will cost one byte if T has alignment of 1 byte (otherwise it should occupy the padding space anyway). There might be a better solution, but I'm not familiar enough with the code to find it!
Here's a link to my changes on my own repo if they're of any use.