首页 > 解决方案 > C中的矩阵乘法(动态内存分配)

问题描述

我正在尝试在 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;
}

标签: cdynamic-memory-allocationmatrix-multiplication

解决方案


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

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

行优先的数组数组

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

行由垂直条(数组的数组)保持在一起。在 C 中,它基本上是一个指针数组。

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

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

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

  • 竖线的内存分配太大了。该数组只需要大小为r,而不需要大小为r * crc是行数和列数)。
  • 行的数组永远不会被释放。

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

*(*(arr1+i)+k)

你可以使用:

arr1[i][k]

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


推荐阅读