c - 为乘法动态分配矩阵 C

标签 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");
        }

    }
}  

代码 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");
        }

    }
}  

我一直在尝试执行代码 2,然后执行代码 2。完成几次后,两者最终都会出现段错误。

最佳答案

int ** 类型就是所谓的参差不齐的数组。您通过首先分配一个“脊柱”数组来创建一个参差不齐的数组,该数组包含指向每个“肋骨”的指针。当您引用 matrix[x][y] 时,您将取消引用“spine”中索引 x 处的指针,然后获取索引“y”处的元素在“肋骨”中。这是一个很好的图表来说明这种结构:

Ragged array in C

您可以阅读 comp.lang.c FAQ list · Question 6.16: How can I dynamically allocate a multidimensional array? (也是上图的来源)了解更多信息。

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

int (*matrix)[colCount] = (int(*)[colCount]) malloc(sizeof(int)*rowCount*colCount);

上面奇怪的语法是你如何declare a pointer to an array in C .需要 *matrix 周围的括号来消除它与 declaring from an array of pointers 的歧义。 . You don't need to cast the result of malloc in C ,所以等价于:

int (*matrix)[colCount] = malloc(sizeof(int)*rowCount*colCount);

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

我更喜欢分配二维数组,因为您可以在一行中完成所有分配,而对于参差不齐的数组,您必须单独设置指向每一行的指针,这通常需要另外几行才能循环。


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

int **mat1 = (int**)malloc(n*sizeof(int));

因为 mat1int** 类型,所以 mat1 中的每个条目都应该是一个 int*。但是,您的 malloc 正在使用 sizeof(int) 为条目分配内存!试试这个:

int **mat1 = (int**)malloc(n*sizeof(int*));

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

(可能还有其他问题,但第一眼看去就是这个。)

关于c - 为乘法动态分配矩阵 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23858139/

相关文章:

ios - 关于应用程序的内存布局和一些变量的逻辑地址

java - OSGI 中声明性服务的动态目标

java - 动态寻址类变量

c - 使用在 C 中动态分配的结构数组

c - 在 "n"行中读取未知数量的整数

c++ - 生成子序列

c - Swift:无法将函数指针转换为 (void*) 以便在 C 风格的第三方库中使用

c - 通过 c/libcurl 使用有效密码访问受密码保护的新闻网站

Julia 中的内存分配

c - 我的链表库不工作