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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:27:02