C语言动态数组代码执行出现Segmentation Fault问题求助
C语言动态数组计算最值/总和时触发段错误的问题修复
问题描述
我写了一段C语言代码,涉及动态数组分配、指针,用来计算数组的最小值、最大值、平均值和总和。数组能正常打印,但总会触发Segmentation Fault(段错误)。我觉得问题出在main函数的调用格式或者参数传递上,试了好几种修改都没解决。运行命令是./a.out 5 6,打印完数组内容就触发段错误了。
原代码
#include <stdio.h> #include <stdlib.h> #include <time.h> void fillArray(int arr[], int arr_size); void printArray(int arr[], int arr_size); void fMin(int arr[], int arr_size, int *q); void fMax(int arr[], int arr_size, int *p); void fSum(int arr[], int arr_size, int *x); int main(int argc, char *argv[]) { int *arr=NULL; int arr_size = atoi(argv[1]); arr = malloc(arr_size * sizeof(int)); if(argc <= 2) { printf("ERROR: invalid command line args"); printf("Expecting: EXCECUTABLE <SIZE>"); } fillArray(arr, arr_size); int i; for(i=0; i<arr_size; i++) { printf("argv[%d] - %2d", arr_size, arr[i]); printf("\n"); } printArray(arr, arr_size); int *min, *max ,avg, sum; int *p; int *q; int *x; avg = sum / arr_size; fMax(arr, arr_size, p); fMin(arr, arr_size, q); fSum(arr, arr_size, &sum); printf("Max: %3d Pos: %3d \n", *max, *p); printf("Min: %3d Pos: %3d \n", *min, *q); printf("Sum: %3d \n", *x); printf("Avg: %3d \n", avg); //for realloc! printArray(arr, arr_size); free(arr); return 0; } void fillArray(int arr[], int arr_size) { srand(time(NULL)); int i; for(i=0; i<arr_size; i++) { arr[i] = rand() % 101; } }//good! void printArray(int arr[], int arr_size) { int i = 0; printf(" POS | VAL \n"); printf("-----------\n"); for(i=0; i<arr_size; i++) { printf(" %3d | %3d \n", i, arr[i]); } }//good! void fMin(int arr[], int arr_size, int *q) { int i; int *min=NULL; min=&arr[i]; for(i=1; i<arr_size; i++) { if(arr[i] < *min) { min = &arr[i]; q = &i; } } }//cant null pointer void fMax(int arr[], int arr_size, int *p) { int i; int *max=NULL; max = &arr[i]; for(i=1; i<arr_size; i++) { if(arr[i] > *max) { max = &arr[i]; p = &i; } } }//good? void fSum(int arr[], int arr_size, int *x) { int i; int sum = *x; for (i=0; i<arr_size; i++) { *x = i + arr[i]; } }//what the heckie goin on here
运行输出
argv[5] - 31 argv[5] - 13 argv[5] - 27 argv[5] - 83 argv[5] - 23 POS | VAL ----------- 0 | 31 1 | 13 2 | 27 3 | 83 4 | 23 zsh: segmentation fault ./a.out 5 6
错误分析与修复
核心问题点
- 野指针泛滥:main里的
min、max、p、q、x都是未初始化的指针,直接解引用或传递给函数会访问非法内存,这是段错误的主要原因。不需要用指针存最值,直接用普通变量就行;位置参数要传变量地址,函数内部给变量赋值。 - 参数检查顺序错误:先执行了
atoi(argv[1])和malloc才检查argc,若用户没传参数,argv[1]是NULL,atoi会出错,且malloc后没检查是否成功。必须先检查参数合法性,再执行后续操作。 - fMin/fMax初始化错误:
min=&arr[i]里的i未初始化,访问随机下标会越界;函数里给q、p赋值时用q=&i,这是把局部变量地址传给形参,函数结束后i销毁,外部拿到野指针。应该把i的值赋值给*q,而非地址。 - fSum逻辑完全错误:循环里每次把
i + arr[i]赋值给*x,根本不是求和;初始时sum未初始化,int sum = *x会读取垃圾值。正确逻辑是从0开始累加arr[i]到*x。 - 平均值计算时机错误:在sum还没计算时就执行
avg = sum / arr_size,此时sum是垃圾值,结果无效,必须在调用fSum后再计算。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <time.h> void fillArray(int arr[], int arr_size); void printArray(int arr[], int arr_size); void fMin(int arr[], int arr_size, int *min_val, int *min_pos); void fMax(int arr[], int arr_size, int *max_val, int *max_pos); void fSum(int arr[], int arr_size, int *sum_val); int main(int argc, char *argv[]) { // 先检查命令行参数合法性 if (argc != 2) { fprintf(stderr, "ERROR: invalid command line args\n"); fprintf(stderr, "Usage: %s <SIZE>\n", argv[0]); return 1; } int arr_size = atoi(argv[1]); if (arr_size <= 0) { fprintf(stderr, "ERROR: size must be positive integer\n"); return 1; } int *arr = malloc(arr_size * sizeof(int)); // 检查malloc是否成功 if (!arr) { fprintf(stderr, "ERROR: failed to allocate memory\n"); return 1; } fillArray(arr, arr_size); printf("Generated array:\n"); int i; for (i = 0; i < arr_size; i++) { printf("arr[%d] - %2d\n", i, arr[i]); } printArray(arr, arr_size); int min_val, max_val, sum_val, avg_val; int min_pos, max_pos; // 调用函数,传递变量地址 fMax(arr, arr_size, &max_val, &max_pos); fMin(arr, arr_size, &min_val, &min_pos); fSum(arr, arr_size, &sum_val); // 计算平均值(整数除法) avg_val = sum_val / arr_size; printf("\nCalculation results:\n"); printf("Max: %3d Pos: %3d \n", max_val, max_pos); printf("Min: %3d Pos: %3d \n", min_val, min_pos); printf("Sum: %3d \n", sum_val); printf("Avg: %3d \n", avg_val); free(arr); return 0; } void fillArray(int arr[], int arr_size) { srand(time(NULL)); for (int i = 0; i < arr_size; i++) { arr[i] = rand() % 101; } } void printArray(int arr[], int arr_size) { printf("\n POS | VAL \n"); printf("-----------\n"); for (int i = 0; i < arr_size; i++) { printf(" %3d | %3d \n", i, arr[i]); } } void fMin(int arr[], int arr_size, int *min_val, int *min_pos) { *min_val = arr[0]; *min_pos = 0; for (int i = 1; i < arr_size; i++) { if (arr[i] < *min_val) { *min_val = arr[i]; *min_pos = i; } } } void fMax(int arr[], int arr_size, int *max_val, int *max_pos) { *max_val = arr[0]; *max_pos = 0; for (int i = 1; i < arr_size; i++) { if (arr[i] > *max_val) { *max_val = arr[i]; *max_pos = i; } } } void fSum(int arr[], int arr_size, int *sum_val) { *sum_val = 0; for (int i = 0; i < arr_size; i++) { *sum_val += arr[i]; } }
内容的提问来源于stack exchange,提问作者user21262461
相关产品推荐
相关产品推荐

