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

动态分配矩阵指定位置赋值时出现segmentation fault问题求助

问题排查:矩阵赋值时的Segmentation Fault错误

核心错误原因

  • 数组索引越界(直接触发段错误的原因):
    输入文件中的行号、列号是1起始的,但C语言数组采用0起始索引。比如输入里的8 3 3,对应行号3、列号3,但你分配的是3行4列的矩阵,行索引范围仅为02,列索引为03。访问A[3][3]会直接越界访问不属于数组的内存,触发Segmentation Fault。

  • feof()的错误使用:
    while(!feof(fp))逻辑存在缺陷——feof()只有在读取操作失败后才会返回true,因此最后一次循环时,fscanf()已经读取失败,但代码仍会执行A[row][col] = val,此时row和col可能是之前的无效值,进一步加剧越界风险。

  • 冗余的fgets()操作:
    readSize()中已经用fscanf()读取了第一行的矩阵尺寸,文件指针已移动到第一行末尾。readFile()里再调用fgets(),会读取第一行剩余的换行符,导致后续fscanf()的读取行为不符合预期,可能漏掉数据或读取错误内容。

  • 内存分配的错误检查无效:
    allocMatrix()中,你在循环分配完每行内存后才检查A == NULL,这完全无效——如果calloc(m, sizeof(int*))失败返回NULL,循环里的*(A + i)会直接访问NULL指针,程序早就崩溃了。正确做法是在calloc后立刻检查是否成功,同时还要检查每行的calloc是否成功,若失败需释放已分配内存避免泄漏。

修正后的关键代码示例

1. 修正索引处理(转换为0起始)

需要将m和n传递给readFile(),读取行号列号后减1:

void readFile (FILE *fp, int **A, int m, int n) {
    int val, row, col;
    // 用fscanf返回值判断读取是否成功,替代feof
    while (fscanf(fp, "%d %d %d", &val, &row, &col) == 3) {
        row--;
        col--;
        // 可选:增加索引合法性检查
        if (row >= 0 && row < m && col >=0 && col < n) {
            A[row][col] = val;
        }
    }
}

2. 修正内存分配的错误检查

int **allocMatrix(int m, int n) {
    int **A = calloc(m, sizeof(int*));
    if (A == NULL) {
        handleErr(ALLOC_ERR);
        return NULL;
    }
    for (int i = 0; i < m; i++) {
        A[i] = calloc(n, sizeof(int));
        if (A[i] == NULL) {
            // 分配失败,释放已分配的所有内存
            for (int j = 0; j < i; j++) {
                free(A[j]);
            }
            free(A);
            handleErr(ALLOC_ERR);
            return NULL;
        }
    }
    return A;
}

3. 修正main函数中readFile的调用

// 原readFile调用改为:
readFile(fp, A, m, n);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:56:54