I have a problem in running my code because the function that I made to have the multiplication between two matrices is still not working even if I have tried different solutions, probably I am missing something important about pointers in the function.
Because the code stops running near the call of the function itself, excuse me if this post is not all correctly done or written but it is my first post on this site.
Here's my code I hope someone could help me.
#include <stdio.h>
#include <stdlib.h>
#define MAXR 50
#define MAXC 50
void printmatrix(int **matrix, int r, int c) {
int i, j;
for (i = 0; i < r; i++) {
printf("\n");
for (j = 0; j < c; j++) {
printf("-%d-", matrix[i][j]);
}
}
}
void matrixprod(int **matrix3, int matrix1[][MAXC], int matrix2[][MAXC], int r1, int c1, int r2, int c2) {
int i, h, k;
h = k = 0;
matrix3[h][k]=0;
for (i = 0; i < c1; i++) {
matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
}
k++;
while (k < c2) {
matrix3[h][k] = 0;
for (i = 0; i < c1; i++) {
matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
}
k++;
}
while (h < r1) {
h++;
k = 0;
matrix3[h][k] = 0;
for (i = 0; i < c1; i++) {
matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
}
k++;
while (k < c2) {
matrix3[h][k] = 0;
for (i = 0; i < c1; i++) {
matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
}
k++;
}
}
}
int main() {
int i, j, h, k;
int r1, r2, c1, c2;
printf("Inserire la dimensione R delle righe e C delle colonne:\n");
scanf("%d%d", &r1, &c1);
int matrix1[r1][c1];
printf("\n**RIEMPIRE LA MATRICE 1 **\n");
for (i = 0; i < r1; i++) {
for (j = 0; j < c1; j++) {
scanf("%d", &matrix1[i][j]);
}
}
printf("Inserire la dimensione R delle righe e C delle colonne:\n");
scanf("%d%d", &r2, &c2);
int matrix2[r2][c2];
printf("\n**RIEMPIRE LA MATRICE 2 **\n");
for (i = 0; i < r2; i++) {
for (j = 0; j < c2; j++) {
scanf("%d", &matrix2[i][j]);
}
}
int **matrix3;
matrix3 = malloc(r1 * sizeof(*matrix3));
for (i = 0; i < r1; i++) {
matrix3[i] = malloc(c2 * sizeof(*matrix3[i]));
}
if (r1 != c2) {
printf("PROD NON ESEGUIBILE");
exit(1);
}
printf("\n****PROD MATRIX*****\n");
matrixprod(matrix3, matrix1, matrix2, r1, c1, r2, c2);
printmatrix(matrix3, r1, c2);
return 0;
}
There are multiple problems in your code:
The 2D matrix sizes are inconsistent between the definition in the main
function and the declaration in the matrixprod
function. You should define the source matrices matrix1
and matrix2
as int matrix1[r2][MAXC];
or int matrix1[MAXR][MAXC];
You can simplify the code: the first row does not need special casing, and using classic for
loops is less error prone than while
loops.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#define MAXR 50
#define MAXC 50
void printmatrix(int **matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf(" %d", matrix[i][j]);
}
printf("\n");
}
printf("\n");
}
void matrixprod(int **matrix3, int matrix1[][MAXC], int matrix2[][MAXC],
int r1, int c1, int r2, int c2) {
if (c1 != r2) {
printf("matrix geometries are incompatible\n");
return;
}
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c2; j++) {
int p = 0;
for (int k = 0; k < c1; k++) {
p += matrix1[i][k] * matrix2[k][j];
}
matrix3[i][j] = p;
}
}
}
int main(void) {
int r1, r2, c1, c2;
printf("Inserire la dimensione R delle righe e C delle colonne:\n");
if (scanf("%d%d", &r1, &c1) != 2 || r1 <= 0 || c1 <= 0 || r1 > MAXR || c1 > MAXC) {
printf("invalid matrix size\n");
return 1;
}
int matrix1[MAXR][MAXC];
printf("\n**RIEMPIRE LA MATRICE 1 **\n");
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c1; j++) {
if (scanf("%d", &matrix1[i][j]) != 1)
return 1;
}
}
printf("Inserire la dimensione R delle righe e C delle colonne:\n");
if (scanf("%d%d", &r2, &c2) != 2 || r2 <= 0 || c2 <= 0 || r2 > MAXR || c2 > MAXC) {
printf("invalid matrix size\n");
return 1;
}
int matrix2[MAXR][MAXC];
printf("\n**RIEMPIRE LA MATRICE 2 **\n");
for (int i = 0; i < r2; i++) {
for (int j = 0; j < c2; j++) {
if (scanf("%d", &matrix2[i][j]) != 1)
return 1;
}
}
if (c1 != r2) {
printf("PROD NON ESEGUIBILE");
exit(1);
}
int **matrix3 = malloc(r1 * sizeof(*matrix3));
if (matrix3 == NULL)
return 1;
for (int i = 0; i < r1; i++) {
matrix3[i] = malloc(c2 * sizeof(*matrix3[i]));
if (matrix3[i] == NULL)
return 1;
}
printf("\n****PROD MATRIX*****\n");
matrixprod(matrix3, matrix1, matrix2, r1, c1, r2, c2);
printmatrix(matrix3, r1, c2);
return 0;
}
Note that you could allocate indirect matrices for all 3 operands, thus removing the MAXC
and MAXR
constraints:
#include <stdio.h>
#include <stdlib.h>
void free_matrix(int **matrix, int rows) {
/* free a dynamic matrix */
if (matrix != NULL) {
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
}
}
int **new_matrix(int rows, int cols) {
/* allocate a dynamic matrix initialized to 0 */
int **matrix = malloc(rows * sizeof(*matrix));
if (matrix != NULL) {
for (int i = 0; i < rows; i++) {
matrix[i] = calloc(cols, sizeof(*matrix[i]));
if (matrix[i] == NULL) {
free_matrix(matrix, i);
return NULL;
}
}
}
return matrix;
}
int **read_matrix(int *rows, int *cols) {
int **matrix;
printf("Inserire la dimensione R delle righe e C delle colonne:\n");
if (scanf("%d%d", rows, cols) != 2 || *rows <= 0 || *cols <= 0) {
printf("invalid matrix size\n");
return NULL;
}
matrix = new_matrix(*rows, *cols);
if (matrix) {
printf("\n**RIEMPIRE LA MATRICE**\n");
for (int i = 0; i < *rows; i++) {
for (int j = 0; j < *cols; j++) {
if (scanf("%d", &matrix[i][j]) != 1) {
free_matrix(matrix, i);
return NULL;
}
}
}
}
return matrix;
}
void printmatrix(int **matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf(" %d", matrix[i][j]);
}
printf("\n");
}
printf("\n");
}
int **matrixprod(int **matrix1, int **matrix2, int r1, int c1, int r2, int c2) {
if (c1 != r2) {
printf("matrix geometries are incompatible\n");
return NULL;
}
int **matrix3 = new_matrix(r1, c2);
if (matrix3) {
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c2; j++) {
int p = 0;
for (int k = 0; k < c1; k++) {
p += matrix1[i][k] * matrix2[k][j];
}
matrix3[i][j] = p;
}
}
}
return matrix3;
}
int main(void) {
int r1, r2, c1, c2;
int **matrix1, **matrix2, **matrix3;
if (!(matrix1 = read_matrix(&r1, &c1)) || !(matrix2 = read_matrix(&r2, &c2)))
return 1;
if (c1 != r2) {
printf("PROD NON ESEGUIBILE");
exit(1);
}
printf("\n****PROD MATRIX*****\n");
matrix3 = matrixprod(matrix1, matrix2, r1, c1, r2, c2);
if (matrix3) {
printmatrix(matrix3, r1, c2);
free_matrix(matrix3, r1);
}
free_matrix(matrix2, r2);
free_matrix(matrix1, r1);
return 0;
}