首页 > 解决方案 > 从映射中删除第一个键值对(在 for 循环中)会导致分段错误

问题描述

我有一个std::map<int, std::string>,我的目标是根据特定条件删除一个键值对。为简单起见,假设它看起来像这样:

int main(int argc, char const *argv[]) {
    std::map<int, std::string> m1;

    m1[-2] = "minus two";
    m1[-1] = "minus one";
    m1[0] = "zero";
    m1[3] = "three";
    m1[4] = "four";

    std::cout << m1.size() << std::endl;

    for (auto &&[key, val] : m1) {
        std::cout << key << ": " << val << std::endl;
        if (key == -2 || key == 3) 
            m1.erase(key);
    }

    std::cout << m1.size() << std::endl;
}

一切看起来都很好。但是,它seg fault在运行时给出:

5
-2: minus two
0: 
Segmentation fault (core dumped)

我注意到这只发生在我尝试擦除第一个键值对时,例如在上述情况下:-2: "minus two". 如果我尝试擦除任何其他键值对(例如第二个键值对:) ,-1: "minus one"那么我不会得到seg fault,例如

    std::cout << m1.size() << std::endl;

    for (auto &&[key, val] : m1) {
        std::cout << key << ": " << val << std::endl;
        if (key == -1 || key == 3) 
            m1.erase(key);
    }

    std::cout << m1.size() << std::endl;

我还注意到,如果我删除循环外的第一个键值对,for那么我不会得到seg fault例如

    std::cout << m1.size() << std::endl;
    m1.erase(-2);

    for (auto &&[key, val] : m1) {
        std::cout << key << ": " << val << std::endl;
        if (key == -2 || key == 3) 
            m1.erase(key);
    }

    std::cout << m1.size() << std::endl;

我注意到的另一件事是,如果只有两个键值对,那么我不会得到seg fault

    m1[-2] = "minus two";
    m1[4] = "four";

    std::cout << m1.size() << std::endl;

    for (auto &&[key, val] : m1) {
        std::cout << key << ": " << val << std::endl;
        if (key == -2 || key == 3) 
            m1.erase(key);
    }

    std::cout << m1.size() << std::endl;

那么,这是预期的行为吗?如果是,那为什么?另外,在这种情况下,如何删除/擦除for循环本身中的第一个键值对?for或者我必须在循环之外删除/擦除它们?

标签: c++dictionarystlsegmentation-fault

解决方案


推荐阅读