C++操作二维数组时触发Segmentation Fault问题求助
问题排查与修复
你的程序出现段错误的核心原因是未初始化变量就用作数组下标,同时还有几个不符合C++标准和逻辑错误的地方,下面逐一说明并给出修复后的代码:
主要错误点
- 未初始化变量直接访问数组:
int a, b; board[a][b] = 1;这里a和b没有被赋值,是随机垃圾值,直接用它们作为数组下标会访问非法内存,触发段错误。而且你把读取a、b的代码写在了赋值之后,逻辑完全颠倒。 - 非标准变长数组(VLA):C++标准不支持
int board[n][n]这种变长数组(部分编译器如GCC是作为扩展支持的),动态数组应该用vector来实现,更安全且符合标准。 - 内存泄漏:
strdup分配的内存没有释放,每次循环都会占用新的内存。 - 输出错误:你用
cout和printf输出到控制台,但程序要求输出到第二个参数指定的文件,应该使用output流。 - 异常处理不当:main函数中抛出异常会导致程序异常终止,命令行程序更适合直接输出错误信息并返回错误码。
- 重复的输入处理:同时使用
strtok和istringstream处理同一行输入,逻辑冗余且容易出错,用istringstream就能完成所有读取操作。
修复后的代码
#include <stdexcept> #include <fstream> #include <sstream> #include <string> #include <vector> #include <iostream> using namespace std; int main(int argc, char** argv) { if (argc < 3) { cerr << "Usage: ./hello <INPUT FILE> <OUTPUT FILE>" << endl; return 1; } ifstream input(argv[1]); ofstream output(argv[2]); if (!input.is_open()) { cerr << "Failed to open input file: " << argv[1] << endl; return 1; } if (!output.is_open()) { cerr << "Failed to open output file: " << argv[2] << endl; return 1; } string line; while (getline(input, line)) { istringstream iss(line); int n, a, b; // 先读取n,再读取a和b if (!(iss >> n >> a >> b)) { cerr << "Invalid line format: " << line << endl; continue; } // 用vector创建二维数组,初始化为0 vector<vector<int>> board(n, vector<int>(n, 0)); // 检查a和b是否在合法范围内,避免越界 if (a >= 0 && a < n && b >=0 && b < n) { board[a][b] = 1; } else { cerr << "Indices out of bounds: a=" << a << ", b=" << b << ", n=" << n << endl; continue; } // 输出到指定文件 for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { output << " " << board[i][j] << " "; } output << endl; } } input.close(); output.close(); return 0; }
关键修改说明
- 用vector替代变长数组:
vector<vector<int>> board(n, vector<int>(n, 0))是C++标准的动态二维数组创建方式,自动管理内存,避免越界风险。 - 调整输入读取顺序:先通过
istringstream读取n、a、b,确认读取成功后再操作数组,避免未初始化变量。 - 添加边界检查:在给
board[a][b]赋值前,检查a和b是否在0到n-1的范围内,防止非法访问。 - 修复输出目标:所有输出都使用
output流,写入到指定的输出文件。 - 完善文件打开检查:添加文件是否成功打开的判断,避免后续操作失败。
- 移除冗余的strtok和strdup:用
istringstream统一处理输入,避免内存泄漏和逻辑混乱。 - 替换异常为错误码:用
cerr输出错误信息并返回1,符合命令行程序的常规处理方式。
内容的提问来源于stack exchange,提问作者Satoly
相关产品推荐
相关产品推荐

