You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键修改说明

  1. 用vector替代变长数组:vector<vector<int>> board(n, vector<int>(n, 0)) 是C++标准的动态二维数组创建方式,自动管理内存,避免越界风险。
  2. 调整输入读取顺序:先通过istringstream读取n、a、b,确认读取成功后再操作数组,避免未初始化变量。
  3. 添加边界检查:在给board[a][b]赋值前,检查a和b是否在0到n-1的范围内,防止非法访问。
  4. 修复输出目标:所有输出都使用output流,写入到指定的输出文件。
  5. 完善文件打开检查:添加文件是否成功打开的判断,避免后续操作失败。
  6. 移除冗余的strtok和strdup:用istringstream统一处理输入,避免内存泄漏和逻辑混乱。
  7. 替换异常为错误码:用cerr输出错误信息并返回1,符合命令行程序的常规处理方式。

内容的提问来源于stack exchange,提问作者Satoly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:05:27