1

Consider the following:

std::unordered_map<int, std::array<float,50>> foo;
...
auto pointerToArray = foo.at(3).data();

I have read this and this. I have the following questions:

  • 1) pointerToArray falls into which category when referring to the invalidation rules, iterator or reference?
  • 2) What are the risks that pointerToArray will get invalidated (assuming its paired key in foo is not erased)?
  • 3) What, if any, difference is there in the answers to these questions between unordered_map and map ?

Unlike vector, array itself will not re-allocate and thus there is not a risk of it changing memory addresses on its own, but as it is inside a unordered/map, the plot thickens.

Update: Found another question that suggests there is no risk of invalidation in this case.

Community
  • 1
  • 1
johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • 1
    It's pretty clear to me that this goes the same as invalidating a pointer to a struct. – zneak Jul 11 '16 at 18:55
  • You should not think in terms of risk. Either it works or it doesn't. – nwp Jul 11 '16 at 18:56
  • 1
    I don't understand how [your second link](http://stackoverflow.com/questions/6438086/iterator-invalidation-rules) does not answer your question. A pointer to something is basically the same as a reference to something. – NathanOliver Jul 11 '16 at 19:00
  • 1
    @NathanOliver I suppose part of the confusion is the standard's use of the word "reference" when I'm not using any C++ references in my example, hence my first question. Edit: I see you just changed your comment to answer the question in this reply. – johnbakers Jul 11 '16 at 19:01
  • @johnbakers Typically a reference is implemented as a pointer. So you can interchange them in this context. – NathanOliver Jul 11 '16 at 19:02
  • As stated in C++11 ISO §23.2.5.8: _Rehashing invalidates iterators, changes ordering between elements, and changes which buckets elements appear in, but does not invalidate pointers or references to elements._. __Since you are calling `at` you are effectively accessing a reference to a mapped value so there are no risks.__ Don't be confused by the fact that you invoke `data()`, which returns a pointer, on the reference returned. – Jack Jul 11 '16 at 19:03
  • `at` returns a reference. Your `pointerToArray` isn't invalidated unless you remove index 3 yourself. – Hatted Rooster Jul 11 '16 at 19:03

1 Answers1

1

Based on the information provided by the first link you provided, pointerToArray should NOT be invalidated by any subsequent changes made to the map, unless you were to erase the element itself from the map. The std::array<float, 50> object will be stored in the heap, and only the pointer (or possibly reference, depending on how std::unordered_map is implemented) to that object will be shuffled around within the map.

Xirema
  • 19,889
  • 4
  • 32
  • 68