结构体Vector中处理元素时遇运行时错误,求问题排查
问题描述
我正在编写一段程序,需求是在结构体Vector(变量名为SOM)中找到第一个成员.v的最大值,随后将该元素以及第二个成员.ref为其±1的元素的.v设为0。但程序持续出现运行时错误,我仍在学习Vector的使用,希望能得到问题排查的帮助。
已通过自定义比较函数完成Vector的排序,以下是尝试编写的代码:
sort(SOM.begin(),SOM.end(),my_cmp); int k= SOM.size(); while(k != 0) { if(SOM[k-1].v > 0) { result += SOM[k-1].v; int a = SOM[k-1].ref; SOM[find_if(SOM.begin(),SOM.end(),[&cm = a](const S& m) -> bool { return (cm-1) == m.ref; }) - SOM.begin()].v = 0; SOM[find_if(SOM.begin(),SOM.end(),[&cm = a](const S& m) -> bool { return (cm+1) == m.ref; }) - SOM.begin()].v = 0; SOM[k-1].v = 0; } k--; }
问题排查与修复方案
核心错误原因
find_if未找到元素时的越界访问:如果find_if遍历完整个vector都没找到符合ref == a±1的元素,会返回SOM.end()。此时SOM.end() - SOM.begin()等于vector的总长度,用这个值作为下标访问SOM(即SOM[SOM.size()])会直接触发数组越界,导致运行时错误。
其他优化点
- 原代码Lambda表达式的捕获方式没必要用引用(
a是基础类型,值捕获更安全),且可以省略显式返回值声明; - 从后往前遍历的逻辑可以结合反向迭代器,更直观且避免下标计算失误。
修正后的代码
sort(SOM.begin(), SOM.end(), my_cmp); for (auto it = SOM.rbegin(); it != SOM.rend(); ++it) { if (it->v > 0) { result += it->v; int target_ref = it->ref; // 处理ref = target_ref -1的元素 auto found_minus = find_if(SOM.begin(), SOM.end(), [target_ref](const S& m) { return m.ref == target_ref - 1; }); if (found_minus != SOM.end()) { found_minus->v = 0; } // 处理ref = target_ref +1的元素 auto found_plus = find_if(SOM.begin(), SOM.end(), [target_ref](const S& m) { return m.ref == target_ref + 1; }); if (found_plus != SOM.end()) { found_plus->v = 0; } // 将当前最大值元素的v设为0 it->v = 0; } }
额外建议
如果ref的值是唯一的或者可以提前建立映射,建议用std::unordered_map<int, S*>来存储ref到结构体指针的映射,这样查找ref±1的元素可以做到O(1)时间复杂度,避免每次全局遍历的O(n)开销,提升程序效率。
内容的提问来源于stack exchange,提问作者Smokem
相关产品推荐
相关产品推荐

