C - 矩阵乘法分割错误

标签 c segmentation-fault dynamic-memory-allocation matrix-multiplication

运行此代码时出现段错误。有人知道为什么吗?谢谢。

#include <stdio.h>

int main()
{
    double **m1, **m2, **mr;
    int m1_rows, m1_cols, m2_rows, m2_cols, mr_rows, mr_cols;
    int i, j, k;

    printf("Enter number of rows for matrix 1: ");
    scanf("%d", &m1_rows);

    printf("Enter number of columns for matrix 1: ");
    scanf("%d", &m1_cols);

    printf("Enter number of rows for matrix 2: ");
    scanf("%d", &m2_rows);

    printf("Enter number of columns for matrix 2: ");
    scanf("%d", &m2_cols);

    //allocate memory for matrix 1 m1
    m1 = (double **) calloc(m1_rows, sizeof(double *));
    for (i = 0; i < m1_rows; i++) {
        m1[i] = (double *) calloc(m1_cols, sizeof(double));
    }

    //allocate memory for matrix 2 m2
    m2 = (double **) calloc(m2_rows, sizeof(double *));
    for (i = 0; i < m2_rows; i++) {
        m2[i] = (double *) calloc(m2_cols, sizeof(double));
    }

    //allocate memory for sum matrix mr
    mr = (double **) calloc(mr_rows, sizeof(double *));
    for (i = 0; i < mr_rows; i++) {
        mr[i] = (double *) calloc(mr_cols, sizeof(double));
    }

    //assign  mr_rows and mr_cols
    mr_rows = m1_rows;
    mr_cols = m2_cols;

    //initialize product matrix
    for (i = 0; i < m1_rows; i++) {
        for (j = 0; j < m2_cols; j++) {
            mr[i][j] = 0;
        }
    }

    //perform matrix multiplication
    for (i = 0; i < m1_rows; i++) {
        for (j = 0; j < m2_cols; j++) {
            mr[i][j] = 0;
            for (k = 0; k < m1_cols; k++) {
                mr[i][j] += m1[i][k] * m2[k][j];
            }
        }
    }

    //print result
    for (i = 0; i < mr_rows; i++) {
        for (j = 0; j < mr_cols; j++) {
            printf("%f\t", mr[i][j]);
        }
    }

    //free memory m1
    for (i = 0; i < m1_rows; i++); {
        free(m1[i]);
    }
    free(m1);

    //free memory m2
    for (i = 0; i < m2_rows; i++); {
        free(m2[i]);
    }
    free(m2);

    //free memory mr
    for (i = 0; i < mr_rows; i++); {
        free(mr[i]);
    }
    free(mr);

    return 0;
}

我使用 valgrind valgrind --tool=memcheck a.out 运行以获取有关段错误的更多信息,但结果超过 30000 个错误,因此它没有将它们打印出来。

最佳答案

您没有分配 mr_rowsmr_cols。它们需要这样设置:

mr_rows = m1_rows;
mr_cols = m2_cols;

这条线不好:

mr[i][j] += m1[i][k] * m2[k][j];

这将越界访问元素,尤其是因为 k 未初始化。您需要在三个嵌套的 for 循环中使用该行代码。实际上,您也可以将归零代码也放入其中。

for(i=0; i<m1_rows; i++){
    for(j=0; j<m2_cols; j++){
        mr[i][j] = 0;
        for(k=0; k<m1_cols; k++){
            mr[i][j] += m1[i][k]*m2[k][j];
        }
    }
}

此外,您所有的内存释放循环都是错误的。而不是

for(i=0; i<m1_rows; i++);{
    free(m1[i]);
}
free(m1);

应该是

for(i=0; i<m1_rows; i++){
    free(m1[i]);
}
free(m1);

那个乱七八糟的分号要了你的命。

您还需要检查 m1 中的列数是否等于 m2 中的行数,即测试 m1_cols == m2_rows.

最后一点。你在这里可怕地复制了你的代码。不要使用三个相同的 for 循环来分配矩阵,也不要使用三个相同的 for 循环来释放矩阵。将这些操作提取到可以从 main 调用的辅助函数中。

这就是我能找到的所有内容!

关于C - 矩阵乘法分割错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9926956/

相关文章:

c - 如何从 Windows 程序访问类似 netstat 的以太网统计信息

c++ - 以编程方式查找 Windows 操作系统卷?

c - 使用霍夫变换找直线,还需要跟踪在这些直线上找到的点

c - strcat 在循环中导致段错误

c - C 函数中的段错误

c - 为什么在尝试释放字符串数组时出现此错误

c - 在 WM_MOUSEMOVE 中绘图

c - 由于 for 循环而使用 ffmpeg 的应用程序出现段错误?

类的 C++ 动态内存分配

c - 将一个元素重新添加到动态数组列表中(从内存中删除后)