1

I wrote a serial program to generate 2 random matrices, multiply them and display the result. I wrote functions for each of the tasks, i.e. generating random matrix, multiplying the matrices and displaying the results. I cannot figure out why both the generated matrices are the same.

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

int **matrix_generator(int row,int col);
int **multiply_matrices(int **matrix_A,int **matrix_B,int rowsA, int colsA,int rowsB,int colsB);
void display_result(int **matrix,int cols,int rows);
void display_matrix(int **matrixA,int cols,int rows);

void main()
{
    int **matrix_A,**matrix_B,**matrix_result,i,j,k,tid,rowsA,colsA,rowsB,colsB;
    printf("Enter the dimensions of Matrix A:\n");
    scanf("%d%d",&rowsA,&colsA);
    printf("Enter the dimensions of Matrix B:\n");
    scanf("%d%d",&rowsB,&colsB);

    if(colsA==rowsB)
    {
        matrix_A = matrix_generator(rowsA,colsA);
        matrix_B = matrix_generator(rowsB,colsB);
        matrix_result = multiply_matrices(matrix_A,matrix_B,rowsA,colsA,rowsB,colsB);

        printf("Matrix A:\n");
        display_matrix(matrix_A,rowsA,colsA);
        printf("\n\n");

        printf("Matrix B:\n");
        display_matrix(matrix_B,rowsB,colsB);
        printf("\n\n");

        display_matrix(matrix_result,rowsB,colsA);

    }
    else
    {
        printf("Check the dimensions of the matrices!\n");
        exit(-1);
    }
}

int **matrix_generator(int row, int col)
{
    int i, j, **intMatrix;

    intMatrix = (int **)malloc(sizeof(int *) * row); 
    srand(time(0));

    for (i = 0; i < row; i++)
    {
        intMatrix[i] = (int *)malloc(sizeof(int *) * col);
        for (j = 0;j<col;j++)
        {
            intMatrix[i][j]=rand()%10;
        }
    }
    return intMatrix;
}

int **multiply_matrices(int **matrix_A,int **matrix_B,int rowsA, int colsA,int rowsB,int colsB)
{
    int i, j, k, **resMatrix;

    resMatrix = (int **)malloc(sizeof(int *) * rowsB); 

    for (i = 0; i < rowsA; i++)
    {
        resMatrix[i] = (int *)malloc(sizeof(int *) * colsA);
        for (j = 0;j<colsB;j++)
        {
            for (k = 0; k < colsA; k++)
                resMatrix[i][j] = resMatrix[i][j] + matrix_A[i][k] * matrix_B[k][j];        
        }
    }
    return resMatrix;
}

void display_matrix(int **matrix, int rows,int cols)
{
    int i,j;
    for (i = 0; i < rows; i = i + 1)
    {
        for (j = 0; j < cols; j = j + 1)
            printf("%d ",matrix[i][j]);
        printf("\n");
    }        
}

OUTPUT:

Enter the dimensions of Matrix A:
4
4
Enter the dimensions of Matrix B:
4
4
Matrix A:
8 7 8 4 
9 8 3 9 
1 2 0 4 
6 0 2 3 


Matrix B:
8 7 8 4 
9 8 3 9 
1 2 0 4 
6 0 2 3 


159 128 93 139 
201 133 114 147 
50 23 22 34 
68 46 54 41 

Can someone please help me understand where I'm going wrong? I have a pretty good idea that it's the matrix_generator() function but cannot seem to figure out what's wrong. Also, It's only multiplying square matrices, if the dimensions are different, like 4X5 and 5X4, I get a segmentation fault.

aBDYsINGH
  • 43
  • 1
  • 10
  • 7
    You need to seed the `rand()` function only once. Do `srand(time(0)); ` at the start of your `main()` function and remove it from else where. – Cherubim Mar 21 '18 at 12:44
  • Your problem is clearly `srand` as pointed out by the previous comments. An other problem is memory leaks here. – Benjamin Barrois Mar 21 '18 at 12:45
  • 3
    `time()` returns the time in seconds. If you call it 2x in rapid succession (< 1sec) you may get the same value. Thus, you could be seeding the RNG with the same number, which will produce the same sequence of "random" numbers. – 001 Mar 21 '18 at 12:47
  • 1
    You are allocating size incorrectly in `resMatrix[i] = (int *)malloc(sizeof(int *) * colsA);` (`sizeof(int *)` vs `sizeof(int)`). I suggest that you read [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/q/42094465/694733). – user694733 Mar 21 '18 at 13:06
  • Possible duplicate of [srand() — why call it only once?](https://stackoverflow.com/questions/7343833/srand-why-call-it-only-once) – n. m. could be an AI Mar 21 '18 at 13:15
  • It migth be a good idea to make a structure ... because having something like "int **matrix_A,**matrix_B,**matrix_result,i,j,k,tid,rowsA,colsA,rowsB,colsB;" is not really friendly. – Tom's Mar 21 '18 at 13:20
  • Thanks. This really helped clear some of my concepts. – aBDYsINGH Mar 21 '18 at 14:32

2 Answers2

3

There are a few issues in your code:

1) You allocate memory incorrectly:

in multiply_matrices should be

resMatrix[i] = (int *)malloc(sizeof(int) * colsB);

and in matrix_generator

intMatrix[i] = (int *)malloc(sizeof(int) * col);

2) In main if you want to print matrix_result call

display_matrix(matrix_result,rowsA,colsB);

Dimensions of [rowsA,colsA] x [rowsB,colsB] is rowsA x colsB

3) malloc returns pointer to uninitialized memory, so you should set resMatrix elements to zero before summing

Content of 2-nd for loop in multiply_matrices should be

    resMatrix[i][j] = 0;
    for (k = 0; k < rowsB; k++)  // CHANGED to rowsB
        resMatrix[i][j] = resMatrix[i][j] + matrix_A[i][k] * matrix_B[k][j];     
rafix07
  • 20,001
  • 3
  • 20
  • 33
1

As pointed out in the comments: You need to seed the rand() function only once. Do srand(time(0)); at the start of your main() function and remove it from elsewhere.

Non-square matrices: There is a bug/typo in multiply_matrices

The line

        for (k = 0; k < colsA; k++)

should be

        for (k = 0; k < rowsA; k++)
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82