C++删除map元素并插入新值时程序异常无返回问题排查
C++ HTML解析程序崩溃问题根因与修复方案
核心问题根因
- 迭代器提前缓存失效:你在遍历map前提前执行了
map<int,string>::iterator ends = check.end();缓存了终止迭代器,但遍历过程中不断执行erase、insert操作修改map结构,map的end()迭代器会动态更新,旧的缓存值已经无效,导致循环终止条件判断错误,大概率触发无限循环或越界访问。 - 遍历中erase导致当前迭代器失效:当你执行
check.erase(index)后,当前正在使用的迭代器itr已经变成野迭代器,后续执行itr++属于未定义行为,是程序无法正常退出的直接诱因。 - size_t返回值强转int隐患:
string::find返回的是无符号类型size_t,你直接赋值给int变量存储,当find返回string::npos(无符号最大值)时会出现整数溢出,导致后续的边界判断逻辑完全错误。 - 简化测试代码未触发崩溃是巧合:你的简化用例中仅会触发1次erase操作,且erase后后续迭代操作刚好没有触发非法内存访问,只是场景简单未暴露问题,不代表逻辑合法。
修复方案
1. 修正map遍历逻辑
不要提前缓存end迭代器,erase元素时正确处理迭代器:
// 错误写法删除 // map<int,string>::iterator ends = check.end(); // for (itr = check.begin(); itr != ends; itr++) // 替换为正确写法 for (auto itr = check.begin(); itr != check.end(); ) { if (itr->second.find(b) != string::npos) { int index = itr->first; string italic_component = itr->second; // erase直接返回下一个有效迭代器,避免野指针 itr = check.erase(itr); // 后续插入新元素的逻辑保持不变 check.insert ({index, italic_component.substr(italic_component.find(italic_component[0]), italic_component.find(b, 0)-1)}); int u = italic_component.find(b, 0); u++; int j = italic_component.find(bb, 0); for (int i = italic_component.find(b, u); i != string::npos && j != string::npos; i = italic_component.find(b, u), j = italic_component.find(bb, j) ) { check.insert({index + j + bb.size() , italic_component.substr(j + bb.size(), i - 1 - (j+bb.size()))}); i++; j++ ; } check.insert({j + index + bb.size() ,italic_component.substr(j + bb.size() , italic_component.size() - 1 - j ) } ) ; } else { // 不需要修改的元素才迭代到下一个位置 itr++; } }
2. 修正string查找返回值类型
所有存储string::find返回值的变量都改为size_t类型,避免整数溢出:
size_t f = type.find(z)+z.size()+1; size_t g = type.find(zz)-f; // 其余k、p、i、j等存储find返回值的变量全部改为size_t类型
3. 补充边界判断
所有substr操作前先判断截取长度是否合法,避免传入负数值触发异常。
内容的提问来源于stack exchange,提问作者Gurasees Singh
相关产品推荐
相关产品推荐

