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

matrizdinamica.c本地运行正常,提交系统报Segmentation Fault及退出状态错误

问题排查:动态矩阵程序段错误与退出状态异常

需求概述

编写matrizdinamica.c程序,实现以下功能:

  • 创建m×n的long int类型矩阵,m和n通过命令行参数argv[1]、argv[2]传入
  • 矩阵元素生成规则:
    • 第1行所有元素为1
    • 第1列所有元素为1
    • 其余元素x[i][j] = x[i-1][j] + x[i][j-1],若结果大于10^6则设为1
  • 矩阵按行输出,每行以\n结尾,元素用%li\t格式,最后一列用%li\n格式
  • 内存分配失败时无输出,返回状态码71;正常运行返回0,终止前释放所有内存

问题现象

本地运行./matrizdinamica 4 5可得到预期输出,编译命令为gcc -ansi -pedantic -Wall -Wextra -Werror matrizdinamica matrizdinamica.c,但提交至教师评测系统时,提示Segmentation Fault (Core Dumped),且退出状态不正确。

现有代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
        int filas = strtol(argv[1], NULL, 10);
        int columnas = strtol(argv[2], NULL, 10);
        long int **x;
        int i;   /* Recorre filas*/
        int j;   /* Recorre columnas */

        /*Reserva de Memoria*/
        x = (long int **) malloc (filas*sizeof(long int*));

        if(x==NULL){
          printf("Error: outta memory");
          exit(71);
        }

        for (i=0;i<filas;i++){
                x[i] = (long int*)malloc(columnas*sizeof(long int));

        if (x[i]==NULL) {
          exit(71);
        }
        }
        /* Damos Valores a la Matriz*/

        for (i=0; i<filas; i++){
          for (j=0; j<columnas; j++){
            if(i==0) x[i][j]=1;
            else if (j==0) x[i][j]=1;
            else {
                x[i][j]=x[i-1][j]+x[i][j-1];
                if (x[i][j]>1000000) x[i][j]=1;
            }
          }
        }

        /* Dibujamos la Matriz en pantalla */
        for (i=0; i<filas; i++){
            /*printf("\n");*/
            for (j=0; j<columnas; j++){
              if (j==columnas-1){
                printf("%li\n", x[i][j]);
              }
              else {
                printf("%li\t", x[i][j]);
              }
            }
        }
           /* if (i < filas -1){
              printf("\n");}
            }*/
        /*printf("\n");*/
        for(i = 0; i < filas; i++){
          free(x[i]);
        }
/*        free(x);*/
        return 0;
}

问题根源分析

  1. 命令行参数未校验

    • 未检查argc是否等于3,若用户未传入足够参数,argv[1]或argv[2]为NULL,调用strtol会直接触发段错误
    • 未校验strtol转换结果,若传入非数字参数,filas或columnas会被设为0,后续malloc(0)返回的指针使用时会引发段错误
  2. 内存分配失败处理不符合要求

    • 内存分配失败时代码打印了错误信息,但需求明确要求无输出,导致评测系统判定输出异常
    • 循环中某一行分配失败时,直接exit(71)未释放已分配的前序行内存,同时顶层指针x也未释放(代码中注释掉了free(x)),违反内存释放要求
  3. 类型匹配错误

    • strtol返回long类型,直接赋值给int类型的filas和columnas,若传入数值超过int范围会导致溢出,引发后续内存分配或数组越界问题

修复方案

1. 补充命令行参数校验

#include <limits.h> // 需引入此头文件获取INT_MAX

// 检查参数数量
if (argc != 3) {
    exit(71);
}

char *endptr1, *endptr2;
long filas_long = strtol(argv[1], &endptr1, 10);
long columnas_long = strtol(argv[2], &endptr2, 10);

// 校验转换有效性与数值范围
if (endptr1 == argv[1] || filas_long <= 0 || filas_long > INT_MAX) {
    exit(71);
}
if (endptr2 == argv[2] || columnas_long <= 0 || columnas_long > INT_MAX) {
    exit(71);
}

int filas = (int)filas_long;
int columnas = (int)columnas_long;

2. 修正内存分配失败处理

x = malloc(filas * sizeof(long int*)); // C中无需强制转换malloc返回值
if (x == NULL) {
    exit(71);
}

for (i = 0; i < filas; i++) {
    x[i] = malloc(columnas * sizeof(long int));
    if (x[i] == NULL) {
        // 释放已分配的所有行
        for (int k = 0; k < i; k++) {
            free(x[k]);
        }
        free(x);
        exit(71);
    }
}

3. 恢复顶层指针释放

取消free(x);的注释,确保所有内存被释放:

for(i = 0; i < filas; i++){
    free(x[i]);
}
free(x); // 恢复此语句

4. 移除错误打印语句

删除内存分配失败时的printf("Error: outta memory");,符合无输出要求。

内容的提问来源于stack exchange,提问作者Miguel Ángel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:10:40