Comments (5)
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.
from robin-map.
You can see the fix in the link:
Fixed aliasing bugs. For example, the Standard permits v.emplace_back(v[0]), which we were mishandling at runtime, and v.push_back(v[0]), which we were guarding against with deficient code (asking “does this object live within our memory block?” doesn’t work in general). The fix involves performing our actions in a careful order, so we don’t invalidate whatever we’ve been given. Occasionally, to defend against aliasing, we must construct an element on the stack, which we do only when there’s no other choice (e.g. emplace(), with sufficient capacity, not at the end).
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.
from robin-map.
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 v[i]
operation may thus invalidate the v[0]
parameter that it gets by reference.
I didn't know that v.push_back(v[0])
with an std::vector
was allowed when v.capacity() == v.size()
, I thought it was an undefined behaviour.
I have to see how this can be done as there are two problems:
- A rehash may occur invalidating all the references to the elements in the hash map
- A element in the hash map may change of place (and thus invalidating any reference to the element) due to the robin hood hashing mechanism. The inserted element may "steal" the bucket of an element and we then have to move the element that was in the bucket further away.
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.
from robin-map.
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 v[0]
expression is executed first and returns a reference to an element inside the bucket array. Afterwards the v[i]
expression is executed which may incur a rehash of the bucket array without being aware of v[0]
. If it happens, the previous reference we got with v[0]
is no more valid and the assignment operation will be undefined.
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]);
}
from robin-map.
Sorry for late response but I do think that v.try_emplace(i, v[0]);
is enough actually, since it will be sort of analogous to v.push_back(v[0])
for vector. While original case might still lead to surprising results for some people, I guess it's similar to possible troubles due to instability of references in case of robin_map versus standard maps.
from robin-map.
Related Issues (20)
- how to write range based for HOT 1
- How to put this into shared memory? HOT 3
- release the latest version to conda-forge? HOT 2
- 1.0.0 fails to build with GCC 12 on Fedora HOT 10
- Do you know how to put robin_map into shared_memory? HOT 1
- Hash Map Insert Stuck in an infinite loop HOT 53
- Broken on Conan HOT 1
- Does robin_map is thread safe?
- CL.exe crash
- find/insert return iterators with read-only second element HOT 3
- aligned_storage is deprecated by C++23 HOT 3
- A C2028 error may be generated when using the c++ 20 module.
- Disable install rule if robin-map is a subproject HOT 3
- Q: Is there a C wrapper? HOT 1
- Robin_map:find() causing segmentation faults HOT 8
- robin_hash crash HOT 1
- CMake: not exporting if IS_SUBPROJECT breaks use through FetchContent HOT 1
- What is the proper way to use robin_map in lambda function for parallelizing?
- Excessive use of memory in some odd cases HOT 5
- Identity hash function by default on GCC HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from robin-map.