【问题标题】:Matrix multiplication(dynamic memory allocation) in CC中的矩阵乘法(动态内存分配)
【发布时间】:2021-10-28 10:43:54
【问题描述】:

我正在尝试在 C 编程中使用动态内存分配来执行矩阵乘法,其中我将用户输入用于每个矩阵的行数和列数。当 r1=c2(mat1 r1xc1 and mat2 r2xc2) 但 mat 4x2 和 mat 2x3 给出分段错误时,输出是正确的。敬请指教。
代码如下:

#include<stdio.h>
#include<stdlib.h>

void create(int **arr,int r,int c)
{
    int i,j;

    for(i=0;i<r;i++)
    {
        arr[i]=(int*)malloc(sizeof(int)*c);

        for(j=0;j<c;j++)
            scanf("%d",*(arr+i)+j);
    }
}

void display(int **arr,int r,int c)
{
    int i,j;

    for(i=0;i<r;i++)
    {
        for(j=0;j<c;j++)
            printf("%d    ",*(*(arr+i)+j));

        printf("\n");
    }
}

void multiply(int **arr1,int **arr2,int **arr3,int r,int c1,int c2)
{
    int i,j,k;

    for(i=0;i<r;i++)
    {
        for(j=0;j<c2;j++)
        {
            arr3[i][j]=0;

            for(k=0;k<c1;k++)
                *(*(arr3+i)+j) += *(*(arr1+i)+k) * *(*(arr2+k)+j);
        }
    }
}

int main()
{
    int **arr1,r1,c1,**arr2,r2,c2,**arr3;

    printf("Enter rows and columns of first matrix: ");
    scanf("%d %d",&r1,&c1);

    arr1=(int**)malloc(sizeof(int*)*r1*c1);
    printf("\nEnter elements of first matrix: ");
    
    create(arr1,r1,c1); 

    printf("\nThe first matrix is: \n");

    display(arr1,r1,c1);

    printf("\nEnter rows and columns of second matrix: ");
    scanf("%d %d",&r2,&c2);

    arr2=(int**)malloc(sizeof(int*)*r2*c2);
    printf("\nEnter elements of second matrix: ");
    
    create(arr2,r2,c2); 

    printf("\nThe second matrix is: \n");

    display(arr2,r2,c2);

    if(c1!=r2)
    {
        printf("\nInvalid dimensions.");
        exit(0);
    }

    arr3=(int**)malloc(sizeof(int*)*r1*c2);

    printf("\nThe product is: \n");

    multiply(arr1,arr2,arr3,r1,c1,c2);

    display(arr3,r1,c2);

    free(arr1);
    free(arr2);
    free(arr3);

    return 0;
}

【问题讨论】:

  • 导致问题的具体输入是什么?

标签: c dynamic-memory-allocation matrix-multiplication


【解决方案1】:

您遇到分段错误的主要原因是您没有为生成的矩阵 arr3 分配矩阵行。您的代码中的更多错误表明您还没有完全理解矩阵的内存组织。

您选择了一个所谓的 row-major 数组数组。这是一个可靠的选择。在内存中,它看起来像这样(对于 3 x 4 矩阵):

每一行都是单独分配的(作为一个数字数组)。这些是水平条。

这些行由竖线组成,竖线是一个数组。在 C 中,它基本上是一个指针数组。

最后,您有一个变量来保存对垂直条的引用(在图中称为 arr)。就是用来表示矩阵的变量。

现在很明显,每个矩阵都需要多个内存分配,一个用于垂直条,多个用于行。竖线在main() 函数中分配,行在create() 函数中分配。但是create() 没有调用arr3。所以会导致分段错误。

您的代码中还有其他问题:

  • 垂直条的内存分配太大。数组的大小只需要 r,而不是 r * c (r c 是行数和列数)。
  • 永远不会释放行的数组。

我还建议使用数组表示法来访问矩阵元素而不是指针算术。因此,而不是:

*(*(arr1+i)+k)

你可以使用:

arr1[i][k]

它适用于小矩阵的原因是运气。它可能覆盖了其他一些数据,这通常会导致崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 2018-01-27
    • 1970-01-01
    • 2017-09-07
    • 2014-05-06
    相关资源
    最近更新 更多