C语言中用函数创建N×N随机0-1矩阵的错误排查
问题:创建N×N随机0-1矩阵时的编译警告与段错误
问题场景
需要实现生成N×N大小、填充随机0和1的矩阵功能,以下是尝试的代码、编译警告及运行错误:
原代码
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <time.h> #include <sys/wait.h> #include <pthread.h> int** createMatr(int N){ int** matr[10][10]; for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ int rnd = rand() % 2; matr[i][j] = rnd; } } return matr; } void setValMatr(int N, int** matr[][10], int** newMatr[][10]){ for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ newMatr[i][j] = matr[i][j]; } } } void printMatr(int N, int** matr[][10]){ for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ printf("%d ",matr[i][j]); } printf("\n"); } } int main(int argc, char* argv[]){ if(argc!=2){ perror("parameter error\n"); } int N = atoi(argv[1]); int** matrix[10][10]; int** helper[10][10]; setValMatr(N,createMatr(N), matrix); setValMatr(N,matrix,helper); printMatr(N, matrix); return 0; }
编译警告
┌──(kali㉿kali)-[~/Desktop/Cprog/Linux2_Lab2] └─$ gcc gvim2135_L2_1.c -o p gvim2135_L2_1.c: In function ‘createMatr’: gvim2135_L2_1.c:15:24: warning: assignment to ‘int **’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion] 15 | matr[i][j] = rnd; | ^ gvim2135_L2_1.c:18:12: warning: returning ‘int ** (*)[10]’ from a function with incompatible return type ‘int **’ [-Wincompatible-pointer-types] 18 | return matr; | ^~~~ gvim2135_L2_1.c:18:12: warning: function returns address of local variable [-Wreturn-local-addr] gvim2135_L2_1.c: In function ‘main’: gvim2135_L2_1.c:47:18: warning: passing argument 2 of ‘setValMatr’ from incompatible pointer type [-Wincompatible-pointer-types] 47 | setValMatr(N,createMatr(N), matrix); | ^~~~~~~~~~~~~ | | | int ** gvim2135_L2_1.c:21:30: note: expected ‘int ** (*)[10]’ but argument is of type ‘int **’ 21 | void setValMatr(int N, int** matr[][10], int** newMatr[][10]){ | ~~~~~~^~~~~~~~~~
运行错误
Segmentation fault
问题分析
- 指针类型完全错误:定义的
int** matr[10][10]是10×10的二维数组,每个元素是指向int指针的指针,但实际需要存储int值的矩阵,类型完全不匹配。 - 返回局部变量地址:
createMatr里的matr是栈上的局部变量,函数返回后内存会被释放,后续访问直接触发未定义行为。 - 类型不匹配赋值:把int类型的随机值赋值给
int**类型的元素,触发类型转换警告,后续访问会把指针值当int处理,必然出错。 - 参数传递类型不兼容:函数返回值与参数的指针类型不匹配,导致调用时类型错误。
修正后的代码
改用动态内存分配实现任意N大小的矩阵,同时修正所有类型问题:
#include <stdio.h> #include <stdlib.h> #include <time.h> // 动态创建N×N的随机0-1矩阵 int** createMatr(int N) { // 分配行指针数组 int** matr = malloc(N * sizeof(int*)); if (!matr) { perror("malloc failed for rows"); exit(EXIT_FAILURE); } // 分配每行内存并填充随机值 for (int i = 0; i < N; i++) { matr[i] = malloc(N * sizeof(int)); if (!matr[i]) { perror("malloc failed for columns"); // 释放已分配内存避免泄漏 for (int j = 0; j < i; j++) free(matr[j]); free(matr); exit(EXIT_FAILURE); } for (int j = 0; j < N; j++) { matr[i][j] = rand() % 2; } } return matr; } // 复制矩阵 void setValMatr(int N, int** matr, int** newMatr) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { newMatr[i][j] = matr[i][j]; } } } // 打印矩阵 void printMatr(int N, int** matr) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { printf("%d ", matr[i][j]); } printf("\n"); } } // 释放矩阵内存 void freeMatr(int N, int** matr) { for (int i = 0; i < N; i++) { free(matr[i]); } free(matr); } int main(int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <N>\n", argv[0]); exit(EXIT_FAILURE); } int N = atoi(argv[1]); if (N <= 0) { fprintf(stderr, "N must be a positive integer\n"); exit(EXIT_FAILURE); } // 初始化随机数种子,保证每次运行结果不同 srand(time(NULL)); int** matrix = createMatr(N); int** helper = createMatr(N); // 先分配内存再复制 setValMatr(N, matrix, helper); printf("Generated matrix:\n"); printMatr(N, matrix); // 释放内存避免泄漏 freeMatr(N, matrix); freeMatr(N, helper); return 0; }
关键修正点
- 用
malloc动态分配内存,支持任意N大小,解决局部变量返回问题 - 修正矩阵类型为
int**,每个元素是int类型,匹配需求 - 添加
srand(time(NULL))初始化随机数种子,保证每次生成的矩阵不同 - 新增内存释放函数,避免内存泄漏
- 完善参数检查、内存分配失败等错误处理逻辑
内容的提问来源于stack exchange,提问作者kiwY12
相关产品推荐
相关产品推荐

