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时直接修改它,从而避免未定义行为的发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值