Reputation: 3691
Consider the following:
struct ExternalBuffer {
ExternalBuffer(const char *s) : s(s){}
const char *s;
bool operator<(const ExternalBuffer& other) const {
return strcmp(s, other.s) < 0;
}
};
char *some_cstr = strdup("hello");
std::map<ExternalBuffer, Value> m;
m.insert(std::make_pair(ExternalBuffer(some_cstr), Value());
auto it = m.find(ExternalBuffer(some_cstr));
free(some_cstr);
m.erase(it);
In the above example, ExternalBuffer
is just a wrapper object for the necessary comparison functions (e.g. operator<()
, or std::hash
).
Is it safe to assume that comparison operations on the key are not performed when erasing by iterator? If no, is anyone aware of implementations which do perform these operations?
The 'safe' thing in my example is of course to free the string after erasing the iterator, but I'm just wondering if that's required.
Upvotes: 0
Views: 44
Reputation: 32742
Keys in a map are const
objects, and they need to stay valid as long as they are in the map. Any change to their state that can change the behavior of the comparison function results in Undefined Behavior.
Because free(some_cstr);
will break this comparison (since it will invoke Undefined Behavior by dereferencing a freed pointer), the your map is broken.
In practical terms, however, it is unlikely that the comparison will need to be run when erasing from a map using an iterator. It is possible that some debug or validation code could complain (if, for example, there is validation the state of that portion of the map before erasing the element).
But is this guaranteed to work by the standard? No.
Upvotes: 4