动态分配矩阵C进行乘法运算

Bha*_*vna 2 c memory dynamic matrix multiplication

我正在尝试对方形矩阵的矩阵乘法进行编码,并且在几次试验的每几次进行后它将继续给出分段错误.我在网站上查找了不同的问题,并尝试了几个方法,使用以下两个代码.

另外,为什么我们需要指向"指针指针"的指针,如int**mat1,**mat2等所给出的?我不知道为什么要这样做,但我在一些答案中看到了它.

代码1

void mxmult()
{
    int n,m,a,b,c,d, sum=0;
    int x,y,z;
    printf("Enter first order [n*n]\n");
    scanf("%d", &n);
    printf("Enter second order [m*m]\n");
    scanf("%d", &m);
    if (n!=m)
    {
        printf("Invalid orders");

    }
    else
    {
        //mem allocate for matrix 1
        int **mat1 = (int**)malloc(n*sizeof(int));
        for(x=0;x<n;x++)
            {
                mat1[x]=(int*)malloc(n*sizeof(int));
            }
        // input matrix 1
        printf("Enter the first matrix entries\n");
        for (a = 0; a <n; a++)
        {
            for (b = 0; b < n; b++)
            {
                scanf("%d", &mat1[a][b]);   
            }
        }
        // memory allocate matrix 2
        int **mat2 = (int**)malloc(m*sizeof(int));
        for(y=0;y<n;y++)
            {
                mat2[y]=(int*)malloc(m*sizeof(int));
            }

        //inpur matrix 2
        printf("Enter the second matrix entries\n");
        for (c = 0; c <n; c++)
        {
            for (d= 0; d < n; d++)
            {
                scanf("%d", &mat2[c][d]);   
            }
        }

        //Memory allocate matrix Mult
        int **mult=(int**)malloc(m*sizeof(int));
        for(z=0;z<m;z++)
            mult[z]=(int*)malloc(m*sizeof(int));
        for (a = 0; a < n; a++)
        {
            for (d = 0; d < m; d++)
            {
                for (c = 0; c < n; c++)
                {
                    sum=sum + (mat1[a][c] *mat2[c][d]);
                }
                mult[a][d] = sum;
                sum= 0;
            }
        }
        printf("Product\n");

        for ( a = 0 ; a < n ; a++ )
        {
            for ( d = 0 ; d < m ; d++)
                printf("%d\t", mult[a][d]);
            printf("\n");
        }

    }
}  
Run Code Online (Sandbox Code Playgroud)

代码2:

void mxmult()
{
    int n,m,a,b,c,d, sum=0;
    int x,y,z;
    printf("Enter first order [n*n]\n");
    scanf("%d", &n);
    printf("Enter second order [m*m]\n");
    scanf("%d", &m);
    if (n!=m)
    {
        printf("Invalid orders");

    }
    else
    {
        //mem allocate for matrix 1
        int **mat1 = (int**)malloc(n*n*sizeof(int));

        // input matrix 1
        printf("Enter the first matrix entries\n");
        for (a = 0; a <n; a++)
        {
            for (b = 0; b < n; b++)
            {
                scanf("%d", &mat1[a][b]);   
            }
        }
        // memory allocate matrix 2
        int **mat2 = (int**)malloc(m*m*sizeof(int));

          //input matrix 2
        printf("Enter the second matrix entries\n");
        for (c = 0; c <n; c++)
        {
            for (d= 0; d < n; d++)
            {
                scanf("%d", &mat2[c][d]);   
            }
        }

        //Memory allocate matrix Mult
        int **mult=(int**)malloc(m*m*sizeof(int));

            // Mx multiplicatn
        for (a = 0; a < n; a++)
        {
            for (d = 0; d < m; d++)
            {
                for (c = 0; c < n; c++)
                {
                    sum=sum + (mat1[a][c] *mat2[c][d]);
                }
                mult[a][d] = sum;
                sum= 0;
            }
        }
        printf("Product\n");

        for ( a = 0 ; a < n ; a++ )
        {
            for ( d = 0 ; d < m ; d++)
                printf("%d\t", mult[a][d]);
            printf("\n");
        }

    }
}  
Run Code Online (Sandbox Code Playgroud)

我一直在尝试执行代码2,然后是code2.两人在几次入职后最终都会出现seg故障.

Dao*_*Wen 9

这种int **类型就是所谓的粗糙数组.首先分配一个"脊椎"数组,创建一个参差不齐的数组,该数组包含指向每个"肋骨"的指针.在引用时matrix[x][y],您将取消引用x"spine" 中索引处的指针,然后将元素置于"rib"中的索引"y"处.这是一个很好的图表说明了这个结构:

C中的衣衫褴褛的阵列

你可以阅读comp.lang.c常见问题列表·问题6.16:如何动态分配多维数组?(也是上图的来源)以获取更多信息.

另一种选择是为矩阵实际分配一个2D数组(我的首选方法).这需要一个支持某些C99结构的编译器,但除了Microsoft C编译器(例如gcc和clang)之外的所有主要编译器似乎默认支持这一点.这是一个例子:

int (*matrix)[colCount] = (int(*)[colCount]) malloc(sizeof(int)*rowCount*colCount);
Run Code Online (Sandbox Code Playgroud)

上面的奇怪语法是如何在C中声明指向数组的指针.*matrix需要括号来消除它与指针数组的声明歧义.您不需要在C中强制转换malloc的结果,因此等效:

int (*matrix)[colCount] = malloc(sizeof(int)*rowCount*colCount);
Run Code Online (Sandbox Code Playgroud)

这为矩阵分配了一个单独的内存块,并且由于编译器知道每行的长度(即colCount),它可以插入数学计算任何2D引用的正确地址.例如,matrix[x][y]相当于((int*)matrix)[x*colCount+y].

我更喜欢分配一个2D数组,因为你可以在一行中完成所有的分配,而对于不规则的数组,你必须分别设置指向每一行的指针,这通常需要另外几行作为循环.


至于你的段错误,这一行看起来很可疑:

int **mat1 = (int**)malloc(n*sizeof(int));
Run Code Online (Sandbox Code Playgroud)

由于mat1是类型int**,每个条目mat1应该是一个int*.但是,您malloc正在使用sizeof(int)为条目分配内存!试试这个:

int **mat1 = (int**)malloc(n*sizeof(int*));
Run Code Online (Sandbox Code Playgroud)

假设您使用的是64位系统,sizeof(int)可能是4(字节),而sizeof(int*)应该是8(字节).这意味着您当前正在分配一半的内存,这意味着当您访问该数组后半部分的条目时会发生不好的事情.使用正确的大小(sizeof(int*))应该解决这个问题.

(可能还有其他问题,但那是第一眼看出来的.)