XDavidT - 7 months ago 32
C Question

# Static Matrix multiplication to dynamic matrix and free in c

I need to build program that make Matrix multiplication.
When i have 2 Static matrix, and the function return pointer to the new dynamic matrix.

My problem is make the multiplication right when I'm moving the matrix into a function.

Main is:

``````        int a_matrix[A_R][A_C] = {  {1,4,6,7},{1,1,5,9} };  //A[][X]&B[X][] --> X Must be Equal !!
int b_matrix[A_C][B_C] = { {5,6,3},{8,2,1}, {4,5,6},{0,9,6} };
int **new_matrix;

new_matrix = multiplying(A_R, A_C, B_C, a_matrix, b_matrix);
print_mtrx(new_matrix,A_R, B_C);
free_mtrx(new_matrix, B_C);
printf("Done...->Exit");
``````

The problem is in the "multiplying" function, and here is it:

``````int multiplying(int a_rows, int a_cols, int b_cols, int A[A_R][A_C], int B[A_C][B_C]) {
//a_cols == b_rows --> from that we understand thar C is build as C[a_rows][b_cols]
int **C,i,j,k;
int sum;
C = (int**)malloc(sizeof(int*)*a_rows);

for (i = 0; i < a_rows; i++) {
C[i] = (int*)malloc(sizeof(int)*b_cols);
for (j = 0; j < b_cols; j++) {
sum = 0;
for (k = 0; k < a_cols; k++)
sum += A[i][k] * B[k][j];
C[i][j] = sum;
}
}

return(C);
}
``````

The free matrix is:

``````void free_mtrx(int **mtrx, int rows) {
int i;
for (i = 0; i < rows; i++)
free(mtrx[i]);
free(mtrx);
}
``````

After Update

Assuming C99 (or C11 and the implementation does not define `__STDC_NO_VLA__`), then the simplest approach is use variable length arrays (VLAs) and to have the calling code allocate the space for the result matrix too. To multiply two matrices, `A[M][N]` and `B[P][Q]` in that order, the values of `N` and `P` must be equal and the result matrix is `C[M][Q]`.

``````#include <stdio.h>

static
void matrix_multiply(int A_rows, int A_cols, int B_cols,
int A[A_rows][A_cols],
int B[A_cols][B_cols],
int C[A_rows][B_cols])
{
for (int i = 0; i < A_rows; i++)
{
for (int j = 0; j < B_cols; j++)
{
int sum = 0;
for (int k = 0; k < A_cols; k++)
sum += A[i][k] * B[k][j];
C[i][j] = sum;
}
}
}

static void print_matrix(const char *tag, int w, int N, int M, int matrix[N][M])
{
printf("%s (%dx%d):\n", tag, N, M);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
printf("%*d", w, matrix[i][j]);
putchar('\n');
}
}

int main(void)
{
int A[3][4] =
{
{ 41, 76, 70, 42, },
{ 70, 62, 77, 74, },
{ 49, 55, 43, 65, },
};
int B[4][5] =
{
{ 73, 33, 42, 72, 65, },
{ 69, 30, 83, 83, 64, },
{ 90, 74, 84, 51, 23, },
{ 62, 45, 84, 46, 43, },
};
int C[3][5];
print_matrix("A", 3, 3, 4, A);
print_matrix("B", 3, 4, 5, B);
matrix_multiply(3, 4, 5, A, B, C);
print_matrix("C", 6, 3, 5, C);
return 0;
}
``````

Output:

``````A (3x4):
41 76 70 42
70 62 77 74
49 55 43 65
B (4x5):
73 33 42 72 65
69 30 83 83 64
90 74 84 51 23
62 45 84 46 43
C (3x5):
17141 10703 17438 14762 10945
20906 13198 20770 17517 13471
15272  9374 15695 13276 10489
``````

If you want to do dynamic memory allocation, then I think you have to pass a pointer to a pointer to a VLA array to the function to get the value returned. That leads to code like this, which is very similar to the previous code — except for the (unchecked) memory allocation. Note that because this uses `static_assert`, it is a C11 program, not a C99 program.

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

#ifdef __STDC_NO_VLA__      // C11
static_assert(0, "No VLA support");
#endif

static void matrix_multiply(int A_rows, int A_cols, int B_cols,
int A[A_rows][A_cols], int B[A_cols][B_cols],
int (**C)[B_cols])
{
(*C) = malloc(sizeof(int [A_rows][B_cols]));  // XXX: Check memory allocation!
for (int i = 0; i < A_rows; i++)
{
for (int j = 0; j < B_cols; j++)
{
int sum = 0;
for (int k = 0; k < A_cols; k++)
sum += A[i][k] * B[k][j];
(*C)[i][j] = sum;
}
}
}

static void print_matrix(const char *tag, int w, int N, int M, int matrix[N][M])
{
printf("%s (%dx%d):\n", tag, N, M);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
printf("%*d", w, matrix[i][j]);
putchar('\n');
}
}

int main(void)
{
enum { N = 3, M = 4, P = 4, Q = 5 };
int A[N][M] =
{
{ 41, 76, 70, 42, },
{ 70, 62, 77, 74, },
{ 49, 55, 43, 65, },
};
int B[P][Q] =
{
{ 73, 33, 42, 72, 65, },
{ 69, 30, 83, 83, 64, },
{ 90, 74, 84, 51, 23, },
{ 62, 45, 84, 46, 43, },
};
static_assert(M == P, "Matrix dimensions are mismatched");
int (*C)[Q];
print_matrix("A", 3, N, M, A);
print_matrix("B", 3, P, Q, B);
matrix_multiply(N, M, Q, A, B, &C);
print_matrix("C", 6, N, Q, C);
free(C);
return 0;
}
``````

This produces the same output as before, of course.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download