基于指针的C语言二维数组矩阵乘法程序错误排查求助
问题分析与修正方案
你遇到的矩阵乘法结果错误,主要是因为矩阵乘法的循环逻辑完全搞反,再加上几个内存分配和函数使用的小问题。我们一步步拆解问题并修复:
核心问题1:矩阵乘法的循环维度逻辑错误
矩阵乘法的规则是:若A是n×k矩阵,B是k×m矩阵,结果C是n×m矩阵,每个元素C[i][j] = Σ(A[i][l] * B[l][j]),其中l遍历0到k-1(也就是A的列/B的行这个公共维度)。
但你的prod函数里循环逻辑完全错位:
for (i = 0; i < n; i++) for (j = 0; j < k; j++) { // j遍历的是A的列数k,但结果C的列数应该是m sum = 0; for (l = 0; l < m; l++) // l遍历的是m,而非公共维度k sum = sum + (x[i][l]*y[l][j]); res[i][j] = sum; }
正确的逻辑应该是:
- j遍历m(结果C的列数,对应B的列)
- l遍历k(公共中间维度,对应A的列/B的行)
核心问题2:prod函数中res未分配内存
你在prod里声明了int **res;,但没有给它分配任何内存就直接赋值res[i][j] = sum,这会触发未定义行为(比如垃圾值、内存访问错误),必须先为res分配n行,每行m个int的空间。
其他次要问题
- main中C的内存分配多余:你提前给C分配了内存,但
prod会返回新分配的结果矩阵,这会导致原C的内存泄漏,直接接收prod的返回值即可。 - read函数的调用冗余:read函数已经通过指针修改了矩阵元素,不需要每次调用都把返回值重新赋值给A/B,直接调用
read(A, i, j);就行。 - 缺少内存释放:虽然不影响程序运行,但手动分配的内存最好在结束前释放,养成良好习惯。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> // 读取矩阵指定位置的元素 void read(int **x, int i, int j) { printf("Give value to store in cell [%d][%d]: ", i, j); scanf("%d", &x[i][j]); } // 矩阵乘法:n×k 的x 乘 k×m 的y,返回n×m的结果矩阵 int **prod(int **x, int **y, int n, int m, int k) { int i, j, l, sum; // 为结果矩阵分配内存 int **res = (int **)malloc(n * sizeof(int *)); for (i = 0; i < n; i++) { res[i] = (int *)malloc(m * sizeof(int)); } // 正确的矩阵乘法循环逻辑 for (i = 0; i < n; i++) { // 遍历结果矩阵的行(对应A的行) for (j = 0; j < m; j++) { // 遍历结果矩阵的列(对应B的列) sum = 0; for (l = 0; l < k; l++) { // 遍历公共中间维度(A的列/B的行) sum += x[i][l] * y[l][j]; } res[i][j] = sum; } } return res; } // 打印指定维度的矩阵 void print(int **x, int r, int c) { int i, j; printf("\nResult Matrix:\n"); for (i = 0; i < r; i++) { for (j = 0; j < c; j ++) { printf("C[%d][%d]: %d\t", i, j, x[i][j]); } printf("\n"); } } int main() { int n, m, k, i, j; printf("Give n, m and k: "); scanf("%d%d%d", &n, &m, &k); int **A, **B, **C; // 分配A的内存:n行k列 A = (int **)malloc(n * sizeof(int *)); for (i = 0; i < n; i++) { A[i] = (int *)malloc(k * sizeof(int)); } // 分配B的内存:k行m列 B = (int **)malloc(k * sizeof(int *)); for (i = 0; i < k; i++) { B[i] = (int *)malloc(m * sizeof(int)); } // 读取矩阵A的元素 printf("\nEnter elements of Matrix A (%dx%d):\n", n, k); for (i = 0; i < n; i++) { for (j = 0; j < k; j++) { read(A, i, j); } } // 读取矩阵B的元素 printf("\nEnter elements of Matrix B (%dx%d):\n", k, m); for (i = 0; i < k; i++) { for (j = 0; j < m; j++) { read(B, i, j); } } // 计算矩阵乘法 C = prod(A, B, n, m, k); // 打印结果 print(C, n, m); // 释放所有分配的内存 for (i = 0; i < n; i++) free(A[i]); free(A); for (i = 0; i < k; i++) free(B[i]); free(B); for (i = 0; i < n; i++) free(C[i]); free(C); return 0; }
测试验证
用你给出的测试用例:
- n=2, m=2, k=2
- A = [[1,2],[3,4]]
- B = [[1,2],[3,4]]
运行后会输出预期结果:
Result Matrix: C[0][0]: 7 C[0][1]: 10 C[1][0]: 15 C[1][1]: 22
内容的提问来源于stack exchange,提问作者Foivos Allayiotis




