Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

segfault when indexing [] into unordered map

Tags:

c++

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?

like image 603
testinggnitset ser Avatar asked Oct 22 '25 05:10

testinggnitset ser


1 Answers

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;
    }
}

Why is the original code wrong?

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.

like image 170
Dietrich Epp Avatar answered Oct 23 '25 20:10

Dietrich Epp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!