分配内存以乘以两个矩阵

时间:2014-07-26 11:14:54

标签: c memory matrix multiplication calloc

回过头来,我写了这段代码来加倍两个矩阵。函数mat_mult在main方法中调用。我想写一些可以采用未知矩阵大小然后根据需要分配内存的东西。当我在main方法中输出结果矩阵时,我似乎遇到了问题。如果我在mat_mult方法中执行printf,矩阵条目就可以了。

为什么主方法中的C矩阵无法正确显示?我释放记忆的方式也是正确的方法吗?

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

void mat_mult(int* p, int* q, int* r, int numP)
{
    int i, j, k, sumC=0;

    for (i = 0; i < numP; i++)
    {
        for (j = 0; j < numP; j++)
        {
            for (k = 0; k < numP; k++)
            {
                sumC = sumC + p[i*numP + k]*q[k*numP + j];
            }
            r[i*numP + j] = sumC;
            sumC = 0;
        }
    }
    for(i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", r[i*numP + j]);
        }
        printf("\n");
    }
}

int main()
{
    int A[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int B[3][3] = {{3, 2, 1}, {6, 5, 4}, {9, 8, 7}};


    int i, j;
    int sizA = sizeof(A)/sizeof(A[0]);

    //int C[3][3] = {0};

    /* sizA is the width of the array */
    int **C = calloc(sizA, sizeof(int*));
    for(i = 0; i < sizA; i++)
    {
        /* sizA is the height */
        C[i] = calloc(sizA, sizeof(int));
    }

    for(i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", C[i][j]);
        }
        printf("\n");
    }
    mat_mult(A[0], B[0], C[0], sizA);


    for(i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", A[i][j]);
        }
        printf("\t");
        for (j = 0; j < 3; j++)
        {
            printf("%d ", B[i][j]);
        }
        printf("\t");
        for (j = 0; j < 3; j++)
        {
            printf("%d ", C[i][j]);
        }
        printf("\n");
    }
    free(C[0]);
    free(C);
    return 0;
}

以下是上述程序的输出。

0 0 0
0 0 0
0 0 0
42 36 30
96 81 66
150 126 102
1 2 3   3 2 1   42 36 30
4 5 6   6 5 4   150 126 102
7 8 9   9 8 7   0 0 0

Process returned -1073741819 (0xC0000005)   execution time : 12.472 s
Press any key to continue.

问题已解决

@Jayesh

非常感谢你的朋友。你的上一个建议奏效了。我只是复制代码的相关部分。

    int i, j;
    int sizA = sizeof(A)/sizeof(A[0]);

//    int C[3][3] = {0};

    /* sizA is the width of the array */
//    int **C = calloc(sizA, sizeof(int*));
//    for(i = 0; i < sizA; i++)
//    {
//        /* sizA is the height */
//        C[i] = calloc(sizA, sizeof(int));
//    }

    int (*C)[sizA] =  calloc(sizA*sizA, sizeof(int*));
    /* Rest of the Code*/

    free(C);

以下是输出的结果。

0 0 0
0 0 0
0 0 0
42 36 30
96 81 66
150 126 102
1 2 3   3 2 1   42 36 30
4 5 6   6 5 4   96 81 66
7 8 9   9 8 7   150 126 102

Process returned 0 (0x0)   execution time : 0.085 s
Press any key to continue.

仍然想知道为什么第一种方法不起作用。但再次感谢所有人和Jayesh。

2 个答案:

答案 0 :(得分:1)

  

这也是我释放记忆的方式,这是正确的方法吗?

否(致电free了解您拨打calloc\malloc的次数。释放内存

for(i = 0; i < sizA; i++)
{
 free(C[i]); 
}
free(C);

我更喜欢像

那样的矩阵内存分配方法
int (*C)[sizA] =  calloc(sizA*sizA, sizeof(int*));

只有free

free(C);

查看有关different ways to allocate array memory

的更多详情

答案 1 :(得分:1)

问题在于您分配内存并使用它。在matmult函数中,您有以下代码:

r[i*numP + j] = sumC;

将结果矩阵r视为单维线性数组。这很好并且可以工作,但这意味着你还必须以这种方式分配它。您的main例程就变成了这个:

int main()
{
    int A[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int B[3][3] = {{3, 2, 1}, {6, 5, 4}, {9, 8, 7}};

    int i, j;
    int sizA = sizeof(A)/sizeof(A[0]);

    /* sizA is the width of the array */
    int *C = calloc(sizA*sizA, sizeof(int));

    for(i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", C[i*3+j]);
        }
        printf("\n");
    }
    mat_mult(A[0], B[0], C, sizA);

    for(i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d ", A[i][j]);
        }
        printf("\t");
        for (j = 0; j < 3; j++)
        {
            printf("%d ", B[i][j]);
        }
        printf("\t");
        for (j = 0; j < 3; j++)
        {
            printf("%d ", C[i*3+j]);
        }
        printf("\n");
    }
    free(C);
    return 0;
}

另一种方法是以这种方式处理所有三个数组,而不是使用多维索引。它不漂亮,但它的工作原理。

或者,对于更好的语法,您可以考虑将C ++用于此类应用程序。