实现图边列表转邻接表时出现Segmentation fault,如何修复?
修复边列表转邻接表代码中的段错误问题
咱们来一步步拆解并修复这个段错误问题:
错误根源分析
你遇到的段错误主要来自两个关键问题:
- 输入读取逻辑完全错误:你想用
cin >> input读取每条边的两个节点,但cin默认会把空格、换行作为分隔符。当你输入4 3 3 2 2 1 4 2时,读取完n=4和m=3后,接下来三次cin >> input会分别拿到"3"、"2"、"2"——根本不是你期望的每条边的两个数字组合。这直接导致strToSotredPair函数里的第一个while循环找不到空格,会一直让pos增长到超出字符串长度,触发非法内存访问,最终得到错误的节点对,访问res数组时越界,引发段错误。 - 字符串处理函数无边界检查:当输入的字符串里没有空格时,函数会访问超出字符串范围的索引,这属于未定义行为,大概率会搞乱后续的内存数据。
修复方案(简化+优化)
其实完全没必要用字符串来处理输入,直接读取整数就能解决问题,还能简化代码:
修复后的完整代码
#include <bits/stdc++.h> using namespace std; int main() { int n, m; cin >> n >> m; vector<set<int>> res(n, set<int>()); for (int i = 0; i < m; ++i) { int u, v; // 直接读取每条边的两个节点 cin >> u >> v; // 生成有序对,保证小节点在前,大节点在后 int a = min(u, v); int b = max(u, v); // 可选:添加合法性检查,避免非法节点导致越界 if (a >= 1 && a <= n && b >= 1 && b <= n) { res[a - 1].insert(b); } else { cerr << "Warning: 节点编号非法 - " << u << " 或 " << v << endl; } } // 输出邻接表 for (int i = 0; i < res.size(); ++i) { cout << res[i].size() << ' '; for (auto item : res[i]) { cout << item << ' '; } cout << endl; } return 0; }
关键修改点说明
- 抛弃字符串解析:直接读取两个整数
u和v,彻底避免了字符串处理带来的越界问题,代码更高效。 - 简化有序对生成:用
min()和max()直接生成有序对,替代原来的字符串处理函数,逻辑更清晰。 - 添加合法性检查:可选的判断能防止输入非法节点编号时触发段错误,同时给出提示信息,方便调试。
测试你的输入
当输入4 3 3 2 2 1 4 2时,程序会正确识别3条边:(3,2)、(2,1)、(4,2),最终输出的邻接表为:
1 2 3 1 3 4 1 2 1 2
内容的提问来源于stack exchange,提问作者alexmosk25
相关产品推荐
相关产品推荐

