C语言读取未知大小矩阵:二级指针传参崩溃问题求助
解决二级指针传递矩阵时的崩溃问题
我完全懂你现在的困惑——能正确读出行列数,但一用int**传递矩阵指针程序就崩溃,而且你想沿用课堂上学过的二级指针方案。咱们先搞明白崩溃的核心原因,再一步步写出能正常跑的代码。
为什么会崩溃?
绝大多数情况是你没有给二级指针分配足够的内存,或者传递指针的方式不对。int**本质是一个指向指针数组的指针:它首先得指向一块能装下row个int*的内存(每个int*对应矩阵的一行),然后每个int*还要指向一块能装下col个int的内存。如果跳过了这些内存分配步骤,int**就是个野指针,访问它指向的内容必然会崩溃。
正确的二级指针实现方案
下面分两种场景给你写示例代码,覆盖你可能遇到的情况:
场景1:主函数分配矩阵,传递给处理函数
如果是主函数里先读取数据、创建矩阵,再传给其他函数处理,直接传int**就行:
#include <stdio.h> #include <stdlib.h> // 处理矩阵的函数,接收二级指针、行列数 void printMatrix(int** mat, int row, int col) { puts("矩阵内容:"); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("%d ", mat[i][j]); } putchar('\n'); } } int main() { int row, col; // 读取行列数(你的代码这部分已经没问题) scanf("%d %d", &row, &col); // 1. 分配行指针数组:让mat指向row个int*的空间 int** mat = (int**)malloc(row * sizeof(int*)); if (mat == NULL) { perror("分配行指针失败"); return 1; } // 2. 为每一行分配列空间 for (int i = 0; i < row; i++) { mat[i] = (int*)malloc(col * sizeof(int)); if (mat[i] == NULL) { perror("分配列空间失败"); // 已分配的内存要释放,避免泄漏 for (int k = 0; k < i; k++) free(mat[k]); free(mat); return 1; } } // 3. 读取row*col个整数填充矩阵 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { scanf("%d", &mat[i][j]); } } // 4. 传递二级指针给处理函数 printMatrix(mat, row, col); // 5. 释放内存:先释放每一行,再释放行指针数组 for (int i = 0; i < row; i++) free(mat[i]); free(mat); return 0; }
场景2:在函数内部分配矩阵,主函数接收
如果是要在单独的函数里完成矩阵分配,那得传递三级指针int***——因为我们要修改主函数里int**指针本身的指向(让它指向malloc出来的内存),只传int**的话,函数里修改的只是形参副本,主函数的指针还是野指针。
#include <stdio.h> #include <stdlib.h> // 分配矩阵的函数,接收三级指针、行列数 void createMatrix(int*** mat, int row, int col) { // 分配行指针数组 *mat = (int**)malloc(row * sizeof(int*)); if (*mat == NULL) { perror("分配行指针失败"); exit(EXIT_FAILURE); } // 分配每一行的列空间 for (int i = 0; i < row; i++) { (*mat)[i] = (int*)malloc(col * sizeof(int)); if ((*mat)[i] == NULL) { perror("分配列空间失败"); // 回滚已分配的内存 for (int k = 0; k < i; k++) free((*mat)[k]); free(*mat); exit(EXIT_FAILURE); } } } void printMatrix(int** mat, int row, int col) { puts("矩阵内容:"); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("%d ", mat[i][j]); } putchar('\n'); } } int main() { int row, col; scanf("%d %d", &row, &col); int** mat = NULL; // 传递二级指针的地址(即三级指针)给分配函数 createMatrix(&mat, row, col); // 填充矩阵 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { scanf("%d", &mat[i][j]); } } printMatrix(mat, row, col); // 释放内存 for (int i = 0; i < row; i++) free(mat[i]); free(mat); return 0; }
测试你的示例输入
把你的示例输入2 3 76 98 -31 30 30 32喂给上面的代码,程序会输出:
矩阵内容: 76 98 -31 30 30 32
避坑要点
- 永远不要直接用
int** mat;就去访问mat[i][j],必须先分配行指针数组和每行的列空间。 - 如果要在函数内修改主函数的二级指针,一定要传它的地址(三级指针)。
- 内存分配失败时要处理,并且回滚已分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user145760
相关产品推荐
相关产品推荐

