C语言矩阵乘法结果显示异常:指针或malloc问题排查
矩阵乘法程序输出异常问题排查与优化建议
问题背景
我编写了一个实现矩阵乘法的C语言程序,matrix1和matrix2能通过displayMatrix函数正常显示正确数值,但计算出的结果matrix3用同一函数显示时出现异常值。我已经修正了multiply函数中首行malloc的int*缺失问题,但异常仍未解决。
可编译代码
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Dimensions { int dim1, dim2; }; struct Dimensions enterDimensions(void); int **createMatrix(int, int); void deleteMatrix(int **); void displayMatrix(int **, int, int); int **multiply(int **, int **, int, int, int); int main(void) { struct Dimensions dimensions1 = enterDimensions(); int **matrix1 = createMatrix(dimensions1.dim1, dimensions1.dim2); displayMatrix(matrix1, dimensions1.dim1, dimensions1.dim2); struct Dimensions dimensions2 = enterDimensions(); int **matrix2 = createMatrix(dimensions2.dim1, dimensions2.dim2);; displayMatrix(matrix2, dimensions2.dim1, dimensions2.dim2); if (dimensions1.dim2 != dimensions2.dim1) { printf("the product of these matrixes does not exist"); } else { int **matrix3 = multiply(matrix1, matrix2, dimensions1.dim1, dimensions1.dim2, dimensions2.dim2); displayMatrix(matrix3, dimensions1.dim1, dimensions2.dim2); deleteMatrix(matrix3); } deleteMatrix(matrix1); deleteMatrix(matrix2); return 0; } struct Dimensions enterDimensions(void) { int dim1; int dim2; struct Dimensions dimensions; printf("dim 1 : \n"); scanf("%d", &dim1); printf("dim 2 : \n"); scanf("%d", &dim2); dimensions.dim1 = dim1; dimensions.dim2 = dim2; return dimensions; } int **createMatrix(int dim1, int dim2) { printf("%s", "\ncreate matrix\n"); int **matrix = malloc(dim1 * sizeof(int *)); for (int i = 0; i < dim1; i++) { matrix[i] = malloc(dim2 * sizeof(int)); } for (int i = 0; i < dim1; i++) { for (int j = 0; j < dim2; j++) { printf("enter (%d,%d)\n", i, j); scanf("%d", &matrix[i][j]); printf("%d\n", matrix[i][j]); } } return matrix; } void deleteMatrix(int **matrix) { printf("%s", "\ndelete matrix\n"); free(matrix); // /!\ Warning : Parameter 'matrix' may point to deallocated memory when called from function 'main' } void displayMatrix(int **matrix, int dim1, int dim2) { if (matrix == NULL) { exit(1); } for (int i = 0; i < dim1; i++) { for (int j = 0; j < dim2; j++) { if (j == dim2 - 1) { printf("[%d]\n", matrix[i][j]); } else { printf("[%d]", matrix[i][j]); } } } } int **multiply(int **matrix1, int **matrix2, int dim11, int dim12, int dim22) { int **matrix3 = malloc(dim11 * sizeof(int*)); // 已修正此处的int*缺失 for (int i = 0; i < dim11; i++) { for (int j = 0; j < dim22; j++) { int cij = 0; for (int k = 0; k < dim12; k++) { if (matrix1 == NULL || matrix2 == NULL) { exit(3); } cij += matrix1[i][k] * matrix2[k][j]; } for (int l = 0; l < dim11; l++) { matrix3[l] = malloc(dim22 * sizeof(int)); } matrix3[i][j] = cij; printf("cij : %d\n", matrix3[i][j]); } } return matrix3; };
程序输出
dim 1 : 2 dim 2 : 2 create matrix enter (0,0) 1 1 enter (0,1) 0 0 enter (1,0) 0 0 enter (1,1) 1 1 [1][0] [0][1] dim 1 : 2 dim 2 : 2 create matrix enter (0,0) 3 3 enter (0,1) 3 3 enter (1,0) 3 3 enter (1,1) 3 3 [3][3] [3][3] cij : 3 cij : 3 cij : 3 cij : 3 [-253143104][428] [-253143104][3] delete matrix delete matrix delete matrix Process finished with exit code 0
异常输出片段:
[-253143104][428] [-253143104][3]
问题根源
1. multiply函数内存分配逻辑错误
你把分配矩阵行内存的循环放在了最内层的j循环里,导致:
- 每次循环
j时,都会重新给所有行分配新内存,之前已经赋值的matrix3[i][j]会被新内存覆盖,写入的数据全部丢失。 - 重复分配内存造成泄漏,未被赋值的内存区域保留垃圾值,显示时出现异常。
2. deleteMatrix函数未完全释放内存
当前deleteMatrix只释放了指向行指针的数组,没有释放每行的内存,会导致严重的内存泄漏。
修复步骤
1. 修正multiply函数的内存分配逻辑
把分配行内存的代码移到最外层循环之前,只执行一次:
int **multiply(int **matrix1, int **matrix2, int dim11, int dim12, int dim22) { int **matrix3 = malloc(dim11 * sizeof(int*)); // 先为所有行分配内存,仅执行一次 for (int l = 0; l < dim11; l++) { matrix3[l] = malloc(dim22 * sizeof(int)); } for (int i = 0; i < dim11; i++) { for (int j = 0; j < dim22; j++) { int cij = 0; for (int k = 0; k < dim12; k++) { if (matrix1 == NULL || matrix2 == NULL) { exit(EXIT_FAILURE); } cij += matrix1[i][k] * matrix2[k][j]; } matrix3[i][j] = cij; printf("cij : %d\n", matrix3[i][j]); } } return matrix3; };
2. 修复deleteMatrix函数,释放全部内存
添加行数参数,先循环释放每行内存,再释放行指针数组:
void deleteMatrix(int **matrix, int rows) { printf("%s", "\ndelete matrix\n"); if (matrix == NULL) return; for (int i = 0; i < rows; i++) { free(matrix[i]); // 释放每行的内存 } free(matrix); // 释放行指针数组 }
同时在main函数调用时传入对应行数:
deleteMatrix(matrix3, dimensions1.dim1); deleteMatrix(matrix1, dimensions1.dim1); deleteMatrix(matrix2, dimensions2.dim1);
代码优化建议
- 添加内存分配检查:每次
malloc后检查返回值是否为NULL,避免空指针访问。示例:int **matrix = malloc(dim1 * sizeof(int *)); if (matrix == NULL) { fprintf(stderr, "Memory allocation failed!\n"); exit(EXIT_FAILURE); } - 统一输入输出格式:简化
enterDimensions的换行逻辑,displayMatrix可调整为更易读的矩阵输出格式。 - 使用标准退出码:用
stdlib.h提供的EXIT_FAILURE代替自定义的exit(1)、exit(3)。 - 优化参数命名:将
multiply的参数dim11、dim12改为rows1、cols1、cols2,提升代码可读性。 - 封装矩阵结构体:把矩阵的指针和维度封装成一个结构体,减少参数传递数量,降低出错概率。示例:
typedef struct { int rows; int cols; int **data; } Matrix;
内容的提问来源于stack exchange,提问作者EagleStar
相关产品推荐
相关产品推荐

