So my unordered map is a mapping from string to double
unordered_map<string,double> u_map;
unordered_map<string,double> other_u_map;
I iterate like so
for (auto it : u_map){
if(isTrue){
other_u_map[it.first] = returnsDouble(); //Segfaults here
u_map.erase(it.first);
}
}
With some test cases it runs perfectly without segfaulting. And then other times it segfaults right after this line, which doesn't make sense because all I'm doing is assigning a double to the key it.first. If the key doesn't exist, then it should create one. Since I'm using C++ datatypes (string and double) it's not an issue with creating my own data structures that causes segfaults or access to mem out of bounds like I've seen in other SO questions. Could it be an issue with using
for (auto it : u_map)
or maybe it's an issue happening before this line
wait I forgot to add that I erase keys in u_map is that the problem?
Unfortunately you cannot use range-based for loops here and you will have to use iterators explicitly instead.
for (auto it = std::begin(u_map); it != std::end(u_map); ) {
// ^ no it++ here
if (isTrue) {
other_u_map[it->first] = returnsDouble();
// ^ changed to -> because it is now iterator
it = u_map.erase(it);
} else {
++it;
}
}
One of the single most common errors in C++ code is using an invalidated iterator. Iterators do not get updated when your collection gets updated. Remember the range based for loop in your question is equivalent to something like this:
for (auto pos = std::start(u_map), end = std::start(u_map);
pos != end; ++pos) {
auto it = *pos;
...
}
The problem is that .erase() invalidates pos, so it is illegal to call ++pos afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With