基于命令行参数与动态内存分配的C语言二维数组段错误排查
动态分配二维数组时出现段错误的问题分析与修复
你尝试通过命令行参数指定行列数来动态分配二维数组并输入数据,但代码存在多个错误导致段错误,具体问题和修复方案如下:
核心错误点
- 命令行参数类型处理错误:
argv的类型是char **,不是int *,argv[1]和argv[2]是字符串,不能直接当作整数使用,必须用atoi()函数将其转换为整数类型。直接使用*argv[1]会取字符串首字符的ASCII值,完全不是你想要的行列数。 - 循环条件错误:内层循环的终止条件错误,比如
for (int j=0; i<argv[2]; j++)这里用了i和argv[2]比较,应该是j < cols(cols是转换后的列数),这种错误会导致循环越界访问内存,触发段错误。 - 未检查命令行参数数量:没有判断
argc是否等于3,当用户没有传入足够参数时,访问argv[1]或argv[2]会导致未定义行为。 - 内存分配未做错误检查:
malloc()可能返回NULL,如果不检查直接使用会导致段错误。 - 未释放动态分配的内存:虽然不是段错误的直接原因,但会造成内存泄漏,属于不良编程习惯。
修正后的代码
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { // 检查命令行参数数量是否正确 if (argc != 3) { printf("用法: %s <行数> <列数>\n", argv[0]); return 1; } int rows = atoi(argv[1]); int cols = atoi(argv[2]); // 检查转换后的行列数是否合法 if (rows <= 0 || cols <= 0) { printf("行列数必须是正整数\n"); return 1; } // 分配行指针数组 int **arr = (int **)malloc(rows * sizeof(int*)); if (arr == NULL) { perror("malloc 行指针失败"); return 1; } // 分配每一行的内存 for (int i = 0; i < rows; i++) { arr[i] = (int *)malloc(cols * sizeof(int)); if (arr[i] == NULL) { perror("malloc 行内存失败"); // 已分配的内存要释放 for (int j = 0; j < i; j++) { free(arr[j]); } free(arr); return 1; } } // 用户输入数据 printf("请输入 %d 个整数:\n", rows * cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { scanf("%d", &arr[i][j]); } } // 输出二维数组 printf("你输入的二维数组是:\n"); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%d ", arr[i][j]); } printf("\n"); } // 释放内存 for (int i = 0; i < rows; i++) { free(arr[i]); } free(arr); return 0; }
说明
- 先用
argc检查参数数量,确保用户传入了行数和列数两个参数。 - 使用
atoi()将命令行参数的字符串转换为整数,得到正确的行列数。 - 每次
malloc后都检查返回值,避免内存分配失败导致的错误。 - 修正了循环条件,确保行列循环的终止条件正确,避免越界访问。
- 程序结束前释放所有动态分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Sayan Banerjee
相关产品推荐
相关产品推荐

