动态分配实现矩阵乘法时返回地址不一致的原因排查
二维矩阵乘法动态分配内存的地址不一致问题修复
核心问题:重复调用导致多次内存分配
你在代码里调用了两次matrixMulti函数:
S = matrixMulti(N, M, L, A, B); printf("\n S address %p\n", matrixMulti(N, M, L, A, B)); // 第二次调用 printf("\n S address %p\n", S); // 第一次调用的返回地址
每次调用matrixMulti都会执行malloc(N * L * sizeof(int)),向堆申请一块新的内存空间,两次分配的地址自然不同,这是地址差值的根本原因。
额外的错误问题
- 内存泄漏
main函数中一开始给S分配了内存:
int *S = (int *)malloc(N * L * sizeof(int));
但之后S = matrixMulti(...)直接覆盖了这个地址,导致最初分配的内存块无法被free,造成内存泄漏。
矩阵索引越界
matrixMulti中计算结果矩阵Mat的索引时用了i * M + j,但Mat是N行L列的矩阵,正确的索引公式应该是i * L + j。用M作为列数会导致当L≠M时,访问的内存超出malloc分配的范围,触发未定义行为,可能导致数据错误或奇怪的内存访问问题。B矩阵分配的语义错误
main中B是M行L列的矩阵,你写的是:
int *B = (int *)malloc(L * M * sizeof(int));
虽然L*M和M*L数值相同,但从语义上应该写成M * L * sizeof(int),避免后续维护时混淆。
修复后的代码示例
#include <stdio.h> #include <stdlib.h> void input(int rows, int cols, int *arr) { printf("输入%d行%d列矩阵元素:\n", rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { scanf("%d", &arr[i * cols + j]); } } } void Array_print(int rows, int cols, int *arr) { printf("%d行%d列矩阵:\n", rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%d ", arr[i * cols + j]); } printf("\n"); } } int *matrixMulti(int N, int M, int L, int *A, int *B) { int *Mat = (int *)malloc(N * L * sizeof(int)); if (Mat == NULL) { // 增加malloc失败的判断 perror("malloc failed"); exit(EXIT_FAILURE); } for (int i = 0; i < N; i++) { for (int j = 0; j < L; j++) { *(Mat + i * L + j) = 0; // 修复索引为i*L+j for (int k = 0; k < M; k++) { *(Mat + i * L + j) += A[i * M + k] * B[k * L + j]; // B的索引也修复为k*L+j } printf("Mat[%d][%d] = %d,Mat地址:%p \n", i, j, *(Mat + i * L + j), Mat); printf("\n"); } } return Mat; } int main() { int N, M, L; printf("input N M L\n "); scanf("%d %d %d", &N, &M, &L); int *A = (int *)malloc(N * M * sizeof(int)); if (A == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } int *B = (int *)malloc(M * L * sizeof(int)); // 修复语义为M*L if (B == NULL) { perror("malloc failed"); free(A); exit(EXIT_FAILURE); } int *S = NULL; // 不再提前分配,避免泄漏 input(N, M, A); Array_print(N, M, A); input(M, L, B); Array_print(M, L, B); S = matrixMulti(N, M, L, A, B); printf("\n S address %p\n", S); // 只打印一次,用同一个返回地址 Array_print(N, L, S); free(A); free(B); free(S); return 0; }
修复后的效果
- 只调用一次
matrixMulti,S的地址唯一,不会出现地址不一致的情况。 - 修复索引后,矩阵乘法的计算结果正确,不会出现越界访问。
- 消除了内存泄漏问题,所有分配的内存都能被正确释放。
内容的提问来源于stack exchange,提问作者Jeong-uk Park
相关产品推荐
相关产品推荐

