views:

529

answers:

3

Am I right in assuming that adding/removing elements to an std::map does not effect the other elements (ie cause them to be relocated in memory) and so that the following is safe:

I looked at various sites with info on the container but only found out about the cases where iterators are invalidated, which I already know...

std::map<std::string,std::string> map;
PopulateMap(map);
std::string &a= map["x"];
AddMoreData(map);
RemoveRandomKeysExceptX(map);
map["x"] = "foo";
std::cout << a << " " << map["x"] << std::endl;//prints "foo foo"
a = "bar";
std::cout << a << " " << map["x"] << std::endl;//prints "bar bar"

I tested some similar code on VC9, which seems to work however that doesn't mean I didn't just get lucky or that it doesn't vary across compilers.

+2  A: 

Map has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. quote taken from sgi docs.

If the iterators are guaranteed not to change then the values they point at also cannot change.

naveen previously had an answer that was similar to this. Unless there is a mistake in my logic what you are doing is safe.

Edit 2: See point 3 in sgi docs to see how getting a value from operator [] is the same as getting the value from an iterator.

CiscoIPPhone
As I pointed out to naveen (not nadeen), the question is not about iterators.
anon
I realise that, but operator [] uses iterators.
CiscoIPPhone
Note that the SGI docs have small discrepances to the Standard library sometimes, when it comes to details.
Johannes Schaub - litb
A: 

Yes you can count on this.

// retrieve reference to string stored at "x"
// note that since [] returns a reference, it must insert an element at "x" if 
// it doesn't exists (in this case an empty string)
std::string &a= map["x"];

// retrieve reference for "x" again and set value to "foo"
map["x"] = "foo";

// use already stored reference
a = "bar";
Magnus Skog
+5  A: 

The Standard is clear on this in 23.1.2/8 about associative containers

The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

Johannes Schaub - litb
+1. I need to keep a copy of the standard on hand. My answer could have been more concise and definitive.
CiscoIPPhone
Yeah it's always a good idea to keep an instance of okular / acroread open so you can quickly lookup stuff =) In this case, i remembered the discussion i had here: http://stackoverflow.com/questions/516007/stdmap-pointer-to-map-key-value-is-this-possible =)
Johannes Schaub - litb
I encourage you to upvote @greg-rogers's answer there. Because it's the right one, obviously, while the accepted answer says that you can't be sure of this. But the standard is pretty clear that pointers keep being valid.
Johannes Schaub - litb
*looks at answers* Which one are you talking about, I seen none by a "greg-rogers"...
Fire Lancer
I mean the question where i link to, above :)
Johannes Schaub - litb