二维数组动态内存分配指针困惑及代码报错咨询
C语言动态二维数组指针问题解析与代码修复
一、指针困惑解答
1. 行内存分配的指针写法
主程序中声明的int **matrix是指向行指针数组的指针,传入函数时用&matrix,对应函数参数int ***pointer。这里的pointer是主程序中matrix变量的地址:
- 错误写法:
pointer = malloc(...)——修改的是函数形参pointer本身的地址,不会影响主程序的matrix变量。 - 正确写法:
*pointer = malloc(sizeof(int*) * row)——*pointer等价于主程序中的matrix(类型为int**),给它分配内存才能让主程序的变量指向新的行指针数组。
2. 行内存分配的指针递增逻辑
动态二维数组的结构是:int**指向一个int*类型的数组(行指针数组),每个int*再指向一行int元素。
*pointer是主程序中的int**矩阵,*pointer + i表示行指针数组中第i个元素的地址(类型为int**)。*(*pointer + i)等价于(*pointer)[i],就是第i行的指针(类型为int*),给它分配sizeof(int)*column的内存,就能让该行指向对应长度的int数组。- 简单说:
*(pointer+i)是错误的(操作的是三级指针的偏移),应该操作*pointer这个二级指针的偏移来定位每一行。
二、代码错误修复与完整代码
核心错误点
- scanf格式错误:原代码中
&pointer[i][j]的pointer是int***,pointer[i][j]是int*,取地址后变成int**,不符合scanf("%d")要求的int*类型。需改为&(*pointer)[i][j]。 - 内存分配错误:input函数中错误修改形参
pointer的地址,未关联到主程序的矩阵变量;行内存分配时操作了三级指针的偏移,而非二级指针。 - calculate函数参数冗余:无需传入三级指针,因为函数不需要修改原矩阵,直接传
int**即可简化逻辑。 - free函数逻辑错误:原代码错误free了三级指针
pointer1,应free主程序中矩阵指向的行指针数组和每行内存。
修复后的完整代码
#include<stdio.h> #include<stdlib.h> void input(int ***pointer, int row, int column) { // 给主程序中的二级指针分配行指针数组内存 *pointer = malloc(sizeof(int*) * row); for(int i = 0; i < row; i++) { // 给每行分配元素内存,*pointer是主程序的二级指针 (*pointer)[i] = malloc(sizeof(int) * column); } for(int i = 0; i < row; i++) { for(int j = 0; j < column; j++) { // *pointer是主程序的矩阵,取对应元素的地址 scanf("%d", &(*pointer)[i][j]); } } } void calculate(int **pointer1, int **pointer2, int row, int column) { int **matrix3 = malloc(sizeof(int*) * row); for(int i = 0; i < row; i++) { matrix3[i] = malloc(sizeof(int) * column); } for(int i = 0; i < row; i++) { for(int j = 0; j < column; j++) { matrix3[i][j] = pointer1[i][j] - pointer2[i][j]; } } // 输出结果 for(int i = 0; i < row; i++) { for(int j = 0; j < column; j++) { printf("%d ", matrix3[i][j]); } printf("\n"); } // 释放临时矩阵内存 for(int i = 0; i < row; i++) { free(matrix3[i]); } free(matrix3); } void frem(int ***pointer1, int row) { // *pointer1是主程序的二级指针,遍历每行释放 for(int i = 0; i < row; i++) { free((*pointer1)[i]); } // 释放行指针数组 free(*pointer1); // 将主程序的矩阵置空,避免野指针 *pointer1 = NULL; } int main() { int row, column; scanf("%d%d", &row, &column); int **matrix1 = NULL, **matrix2 = NULL; input(&matrix1, row, column); input(&matrix2, row, column); calculate(matrix1, matrix2, row, column); frem(&matrix1, row); frem(&matrix2, row); return 0; }
修复说明
- input函数:通过
*pointer操作主程序的矩阵变量,正确分配行指针数组和每行内存;scanf时取(*pointer)[i][j]的地址,匹配int*类型。 - calculate函数:改为接收
int**参数,直接访问矩阵元素,逻辑更清晰。 - frem函数:通过
*pointer1访问主程序的矩阵,依次释放每行内存和行指针数组,最后将矩阵置空防止野指针。
内容的提问来源于stack exchange,提问作者Rakesh
相关产品推荐
相关产品推荐

