c – 将[]索引到无序映射时的段错误

所以我的无序地图是从字符串到双精度的映射

unordered_map<string,double> u_map;
unordered_map<string,double> other_u_map;

我这样迭代

for (auto it : u_map){
   if(isTrue){
       other_u_map[it.first] = returnsDouble(); //Segfaults here
       u_map.erase(it.first);
   }
}

对于一些测试用例,它运行完美,没有segfaulting.然后其他时候它会在这一行之后发生段错误,这没有任何意义,因为我所做的就是为它指定一个双键.如果密钥不存在,那么它应该创建一个.由于我使用的是C数据类型(字符串和双精度型),所以创建我自己的数据结构不会导致段错误或访问mem超出界限,就像我在其他SO问题中看到的那样.这可能是使用的问题

for (auto it : u_map)

或者这可能是在这一行之前发生的问题

等我忘了添加我擦除u_map中的键是问题吗?

最佳答案
不幸的是,你不能在这里使用基于范围的for循环,你必须明确地使用迭代器.

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

为什么原始代码错了?

C代码中最常见的一个错误是使用无效的迭代器.当您的集合更新时,迭代器不会更新.请记住,您的问题中基于for循环的范围等效于:

for (auto pos = std::start(u_map), end = std::start(u_map);
     pos != end; ++pos) {
    auto it = *pos;
    ...
}

问题是.erase()使pos无效,因此之后调用pos是违法的.

转载注明原文:c – 将[]索引到无序映射时的段错误 - 代码日志