You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态分配实现矩阵乘法时返回地址不一致的原因排查

二维矩阵乘法动态分配内存的地址不一致问题修复

核心问题:重复调用导致多次内存分配

你在代码里调用了两次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)),向堆申请一块新的内存空间,两次分配的地址自然不同,这是地址差值的根本原因。

额外的错误问题

  1. 内存泄漏
    main函数中一开始给S分配了内存:
int *S = (int *)malloc(N * L * sizeof(int));

但之后S = matrixMulti(...)直接覆盖了这个地址,导致最初分配的内存块无法被free,造成内存泄漏。

  1. 矩阵索引越界
    matrixMulti中计算结果矩阵Mat的索引时用了i * M + j,但Mat是N行L列的矩阵,正确的索引公式应该是i * L + j。用M作为列数会导致当L≠M时,访问的内存超出malloc分配的范围,触发未定义行为,可能导致数据错误或奇怪的内存访问问题。

  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:35:19