存在多个问题:
-
deleteMatrix
仅释放行指针数组。您应该传递行数(
dim1
)因此它释放了保存矩阵值的各个行。
-
displayMatrix
应该简化:应该在内部循环的末尾无条件地输出换行符。
-
enterDimensions
和
createMatrix
应检测并报告输入错误和分配失败。
-
multiplyMatrix
没有正确分配结果矩阵:它的行被多次分配给每个结果单元格值。最终结果是大量内存泄漏,并且只有每行的最后一个值在最终结果矩阵中显示正确。
以下是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
struct Dimensions {
int dim1, dim2;
};
struct Dimensions enterDimensions(void);
int **allocateMatrix(int rows, int cols);
int **createMatrix(int rows, int cols);
void deleteMatrix(int **mat, int rows);
void displayMatrix(int **mat, int rows, int cols);
int **multiply(int **mat1, int **mat2, int dim11, int dim12, int dim22);
int main(void) {
struct Dimensions dimensions1 = enterDimensions();
int **matrix1 = createMatrix(dimensions1.dim1, dimensions1.dim2);
printf("matrix1:\n");
displayMatrix(matrix1, dimensions1.dim1, dimensions1.dim2);
struct Dimensions dimensions2 = enterDimensions();
int **matrix2 = createMatrix(dimensions2.dim1, dimensions2.dim2);;
printf("matrix2:\n");
displayMatrix(matrix2, dimensions2.dim1, dimensions2.dim2);
if (dimensions1.dim2 != dimensions2.dim1) {
printf("cannot compute the product of these matrices: dimensions do not match\n");
deleteMatrix(matrix1, dimensions1.dim1);
deleteMatrix(matrix2, dimensions2.dim1);
return 1;
} else {
int **matrix3 = multiply(matrix1, matrix2, dimensions1.dim1, dimensions1.dim2, dimensions2.dim2);
printf("matrix3:\n");
displayMatrix(matrix3, dimensions1.dim1, dimensions2.dim2);
deleteMatrix(matrix3, dimensions2.dim2);
deleteMatrix(matrix1, dimensions1.dim1);
deleteMatrix(matrix2, dimensions2.dim1);
return 0;
}
}
struct Dimensions enterDimensions(void) {
struct Dimensions dimensions;
printf("enter dim 1: ");
if (scanf("%d", &dimensions.dim1) != 1) {
printf("invalid input\n");
exit(1);
}
printf("enter dim 2: ");
if (scanf("%d", &dimensions.dim2) != 1) {
printf("invalid input\n");
exit(1);
}
return dimensions;
}
int **allocateMatrix(int dim1, int dim2) {
if (dim1 <= 0 || dim2 <= 0) {
printf("invalid dimensions: %d,%d\n", dim1, dim2);
exit(1);
}
int **matrix = calloc(dim1, sizeof(int *));
if (!matrix) {
printf("allocation failed\n");
exit(1);
}
for (int i = 0; i < dim1; i++) {
matrix[i] = calloc(dim2, sizeof(int));
if (!matrix[i]) {
printf("allocation failed\n");
exit(1);
}
}
return matrix;
}
int **createMatrix(int dim1, int dim2) {
int **matrix = allocateMatrix(dim1, dim2);
for (int i = 0; i < dim1; i++) {
for (int j = 0; j < dim2; j++) {
printf("enter (%d,%d): ", i, j);
if (scanf("%d", &matrix[i][j]) != 1) {
printf("invalid input\n");
exit(1);
}
//printf("%d\n", matrix[i][j]);
}
}
return matrix;
}
void deleteMatrix(int **matrix, int dim1) {
if (matrix == NULL)
return;
for (int i = 0; i < dim1; i++) {
free(matrix[i]);
}
free(matrix);
}
void displayMatrix(int **matrix, int dim1, int dim2) {
if (matrix == NULL)
return;
for (int i = 0; i < dim1; i++) {
for (int j = 0; j < dim2; j++) {
printf("[%d]", matrix[i][j]);
}
printf("\n");
}
}
int **multiply(int **matrix1, int **matrix2, int dim11, int dim12, int dim22) {
if (matrix1 == NULL || matrix2 == NULL)
return NULL;
int **matrix3 = allocateMatrix(dim11, dim22);
for (int i = 0; i < dim11; i++) {
for (int j = 0; j < dim22; j++) {
int cij = 0;
for (int k = 0; k < dim12; k++) {
cij += matrix1[i][k] * matrix2[k][j];
}
matrix3[i][j] = cij;
}
}
return matrix3;
}
请注意,将维度和数据存储到
Matrix
结构以下是使用此方法的修改版本:
#include <stdio.h>
#include <stdlib.h>
typedef struct Matrix {
int dim1, dim2;
int **data;
} Matrix;
Matrix *matrix_allocate(int rows, int cols);
Matrix *matrix_input(void);
void matrix_delete(Matrix *matrix);
void matrix_display(Matrix *matrix);
Matrix *matrix_multiply(Matrix *mat1, Matrix *mat2);
int main(void) {
Matrix *matrix1 = matrix_input();
if (!matrix1)
return 1;
printf("matrix1:\n");
matrix_display(matrix1);
Matrix *matrix2 = matrix_input();
if (!matrix2)
return 1;
printf("matrix2:\n");
matrix_display(matrix2);
if (matrix1->dim2 != matrix2->dim1) {
printf("cannot compute the product of these matrices: dimensions do not match\n");
matrix_delete(matrix1);
matrix_delete(matrix2);
return 1;
} else {
Matrix *matrix3 = matrix_multiply(matrix1, matrix2);
if (!matrix3)
return 1;
printf("matrix3:\n");
matrix_display(matrix3);
matrix_delete(matrix3);
matrix_delete(matrix1);
matrix_delete(matrix2);
return 0;
}
}
Matrix *matrix_allocate(int dim1, int dim2) {
if (dim1 <= 0 || dim2 <= 0) {
printf("invalid dimensions: %d,%d\n", dim1, dim2);
return NULL;
}
Matrix *matrix = calloc(1, sizeof(Matrix));
if (!matrix)
return NULL;
matrix->dim1 = dim1;
matrix->dim2 = dim2;
matrix->data = calloc(dim1, sizeof(int *));
if (!matrix->data) {
printf("allocation failed\n");
free(matrix);
return NULL;
}
for (int i = 0; i < dim1; i++) {
matrix->data[i] = calloc(dim2, sizeof(int));
if (!matrix->data[i]) {
printf("allocation failed\n");
while (i-- > 0) {
free(matrix->data[i]);
}
free(matrix->data);
free(matrix);
return NULL;
}
}
return matrix;
}
void matrix_delete(Matrix *matrix) {
if (matrix != NULL) {
for (int i = 0; i < matrix->dim1; i++) {
free(matrix->data[i]);
}
free(matrix->data);
free(matrix);
}
}
Matrix *matrix_input(void) {
int dim1, dim2;
printf("enter dim 1: ");
if (scanf("%d", &dim1) != 1) {
printf("invalid input\n");
return NULL;
}
printf("enter dim 2: ");
if (scanf("%d", &dim2) != 1) {
printf("invalid input\n");
return NULL;
}
Matrix *matrix = matrix_allocate(dim1, dim2);
if (!matrix)
return NULL;
for (int i = 0; i < dim1; i++) {
for (int j = 0; j < dim2; j++) {
printf("enter (%d,%d): ", i, j);
if (scanf("%d", &matrix->data[i][j]) != 1) {
printf("invalid input\n");
matrix_delete(matrix);
return NULL;
}
}
}
return matrix;
}
void matrix_display(Matrix *matrix) {
if (matrix == NULL)
return;
for (int i = 0; i < matrix->dim1; i++) {
for (int j = 0; j < matrix->dim2; j++) {
printf("[%d]", matrix->data[i][j]);
}
printf("\n");
}
}
Matrix *matrix_multiply(Matrix *matrix1, Matrix *matrix2) {
if (matrix1 == NULL || matrix2 == NULL || matrix1->dim2 != matrix2->dim1)
return NULL;
Matrix *matrix3 = matrix_allocate(matrix1->dim1, matrix2->dim2);
if (!matrix3)
return NULL;
for (int i = 0; i < matrix1->dim1; i++) {
for (int j = 0; j < matrix2->dim2; j++) {
int cij = 0;
for (int k = 0; k < matrix1->dim2; k++) {
cij += matrix1->data[i][k] * matrix2->data[k][j];
}
matrix3->data[i][j] = cij;
}
}
return matrix3;
}