C++程序触发Segmentation fault (core dumped)错误,求问题排查
Segmentation fault when using unordered_map instead of map in C++
运行以下C++程序时控制台报错:Segmentation fault (core dumped),进程返回码139 (0x8B)。之前使用map时程序运行正常,改为unordered_map后问题复现。
代码如下:
#include <iostream> #include <vector> #include <unordered_map> using namespace std; int main() { vector<int> nums = {2,1,9,4,4,56,90,3}; int target = 8; unordered_map<int,int> m; for(int i=0;i<nums.size();i++){ m[nums[i]] = i; } int req_num; for (int i=0; i<nums.size(); i++){ req_num = target - nums[i]; auto search = m.find(req_num); int first = search->first; int second = search->second; if(first == req_num && second != i){ cout << second << endl; } } return 0; }
错误原因
问题核心是直接解引用unordered_map::find()返回的迭代器,未先检查是否找到有效元素。
当m.find(req_num)找不到对应键时,会返回unordered_map::end()迭代器——这个迭代器指向容器末尾的“哨兵”位置,并非有效元素。直接访问search->first或search->second属于未定义行为,必然触发段错误。
至于之前用map时没报错,只是巧合:要么当时的测试数据中所有req_num都能在map中找到,要么map的内存布局刚好没触发崩溃(未定义行为的结果是不确定的,可能正常运行也可能崩溃)。本质上用map时同样存在这个隐患,只是没暴露出来。
修复方案
在解引用迭代器前,必须先判断迭代器是否有效:
for (int i=0; i<nums.size(); i++){ req_num = target - nums[i]; auto search = m.find(req_num); // 先检查是否找到元素,再判断索引是否不同 if (search != m.end() && search->second != i){ cout << search->second << endl; } }
另外,原代码中first == req_num的判断完全多余:find(req_num)找到的元素键必然等于req_num,只要迭代器有效就无需额外验证。
额外优化提示
原代码构建unordered_map时,重复元素会覆盖之前的索引(比如nums中的两个4,最终m[4]会存储第二个4的索引4)。如果需要保留每个键对应的所有索引,可以改用unordered_map<int, vector<int>>存储位置列表。
内容的提问来源于stack exchange,提问作者sudheer
相关产品推荐
相关产品推荐

