自学内容网 自学内容网

C++ 范围for循环时对容器进行删除

在 C++ 中,在使用范围for循环时对容器进行修改(例如删除元素)可能会导致未定义行为。这是因为范围for循环的迭代器可能会在容器被修改后失效。在你的代码中,positionMap.erase(key) 会在循环过程中删除元素,这样会导致迭代器失效,进而引发潜在的崩溃或未定义行为。

为了安全地删除元素,可以采用如下方法:

  1. 使用标准for循环:在标准for循环中,可以显式控制迭代器的行为,并在删除元素后手动更新迭代器。

  2. 延迟删除:首先记录要删除的键,循环结束后再删除这些键。

这里是第一种方法的实现:

#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> positionMap = {{"yd_1", 10}, {"yd_2", 20}, {"keep", 30}, {"yd_3", 40}};

    for (auto it = positionMap.begin(); it != positionMap.end();) {
        if (it->first.substr(0, 3) == "yd_") {
            std::cout << "Erasing: " << it->first << std::endl;
            it = positionMap.erase(it); // 删除元素后,更新迭代器。erase返回删除元素的下一个迭代器
        } else {
            ++it; // 不删除时,正常递增迭代器
        }
    }

    return 0;
}

第二种方法的实现:

#include <iostream>
#include <map>
#include <string>
#include <vector>

int main() {
    std::map<std::string, int> positionMap = {{"yd_1", 10}, {"yd_2", 20}, {"keep", 30}, {"yd_3", 40}};

    // 记录要删除的键
    std::vector<std::string> keys_to_delete;

    for (const auto &pair : positionMap) {
        if (pair.first.substr(0, 3) == "yd_") {
            std::cout << "Marking for deletion: " << pair.first << std::endl;
            keys_to_delete.push_back(pair.first);
        }
    }

    // 删除记录的键
    for (const auto &key : keys_to_delete) {
        positionMap.erase(key);
    }

    std::cout << "Remaining elements:" << std::endl;
    for (const auto &pair : positionMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

这两种方法都可以避免在遍历positionMap时直接修改它,从而避免未定义行为的发生。


原文地址:https://blog.csdn.net/weixin_57097753/article/details/140593398

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!