GithubHelp home page GithubHelp logo

Comments (5)

Tessil avatar Tessil commented on August 15, 2024 2

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.

brenoguim avatar brenoguim commented on August 15, 2024 1

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.

Tessil avatar Tessil commented on August 15, 2024

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.

Tessil avatar Tessil commented on August 15, 2024

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.

Predelnik avatar Predelnik commented on August 15, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.