C++ 范围for循环时对容器进行删除
在 C++ 中,在使用范围for循环时对容器进行修改(例如删除元素)可能会导致未定义行为。这是因为范围for循环的迭代器可能会在容器被修改后失效。在你的代码中,positionMap.erase(key)
会在循环过程中删除元素,这样会导致迭代器失效,进而引发潜在的崩溃或未定义行为。
为了安全地删除元素,可以采用如下方法:
-
使用标准for循环:在标准for循环中,可以显式控制迭代器的行为,并在删除元素后手动更新迭代器。
-
延迟删除:首先记录要删除的键,循环结束后再删除这些键。
这里是第一种方法的实现:
#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)!