2

this is the program I have written for multiplying two matrices.

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

void allocate(int **mat,int m,int n)
{
    int i;
    mat = (int**)malloc(m*sizeof(int*));
    for(i=0;i<m;i++)
    *(mat+i) = (int*)malloc(n*sizeof(int));
}

void read(int **mat,int m,int n)
{
    int i,j;
    for(i=0;i<m;i++)
    for(j=0;j<n;j++)
    {
        printf("Enter the element in row number %d and column number %d\n",i+1,j+1);
        scanf("%d",*(mat+i)+j);
    }
}

void multiply(int **mat1,int m,int n,int **mat2,int p,int **prod)
{
    int i,j,k;
    for(i=0;i<m;i++)
    for(j=0;j<p;j++)
    {
        *(*(prod+i)+j) = 0;
        for(k=0;k<n;k++)
        *(*(prod+i)+j) += (*(*(mat1+i)+k))*(*(*(mat2+k)+j));
    }
}

void PRINT(int **mat,int m,int n)
{
    int i,j;
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            printf("%d\t",*(*(mat+i)+j));
        }
    printf("\n\n\n");
    }
}

int main()
{
    int m,n,p,**mat1,**mat2,**prod;
    printf("Enter the number of rows of the first matrix to be multiplied\n");
    scanf("%d",&m);
    printf("Enter the number of columns of the first matrix to be multiplied\n");
    scanf("%d",&n);
    printf("Enter the number of columns of the second matrix to be multiplied\n");
    scanf("%d",&p);
    allocate(mat1,m,n);
    allocate(mat2,n,p);
    allocate(prod,m,p);
    printf("Enter the entries of the first matrix\n");
    read(mat1,m,n);
    printf("Enter the entries of the second matrix\n");
    read(mat2,n,p);
    printf("The first input matrix is\n");
    PRINT(mat1,m,n);
    printf("The second input matrix is\n");
    PRINT(mat2,n,p);
    multiply(mat1,m,n,mat2,p,prod);
    printf("The product matrix is\n");
    PRINT(prod,m,p);
    return 0;
}

The scanf function used in the read function definition is not working, it just doesn't allow us to give any input and stops unexpectedly. I have used it the same way in another program to find the trace of a matrix and it is fine there.

Please help me finding the error.

Martund
  • 291
  • 1
  • 8

2 Answers2

3

Your allocate function receives a copy of the int ** passed as its first argument and, thus, the variables used as this argument in your main function are not modified by it.

To get round this, you could pass the argument as a "pointer to int**" (i.e. int*** mat) - but this starts to get messy (and you'll need to adjust the code inside allocate accordingly). A better way is to redefine the allocate function to return the created pointer, as such:

int** allocate(int m, int n)
{
    int i;
    int** mat = malloc(m * sizeof(int*));
    for (i = 0; i < m; i++)
        *(mat + i) = malloc(n * sizeof(int));
    return mat;
}

Then, in your main function, modify the calls to allocate as follows:

    mat1 = allocate(m, n);
    mat2 = allocate(n, p);
    prod = allocate(m, p);

You will (of course) need the proper code (at some point) to free the allocated matrices.

Also, see Do I cast the result of malloc?

Adrian Mole
  • 43,040
  • 110
  • 45
  • 72
1

Your allocation function is very wrong.

Currently, you allocate the local variable mat in allocate and you don't return it nor pas it by pointer, thus, the value is lost at the end of the function (in c, arguments are always passed by value) and you write on invalid data. You have an undefind behavior and as you are lucky, your program segfaults.

Therefore, when you allocate a data, you have to allocate a pointer to this data. Here your data is a int** . That means that your allocate function must take an int*** as an input.

Your program should work with :

void allocate(int ***mat, int m,int n)
{
    int i; 
    *mat = (int**)malloc(m*sizeof(int*));
    for(i=0;i<m;i++)
    *(*mat+i) = (int*)malloc(n*sizeof(int));
}

Another (maybe cleaner) way to deal with that issue is to return the allocated mat, like below

int** allocate(int m,int n)
{
    int i; 
    int **mat = (int**)malloc(m*sizeof(int*));
    for(i=0;i<m;i++)
    *(mat+i) = (int*)malloc(n*sizeof(int));
    return mat;
}

Also, to debug this kind of issue, valgrind could be really helpful the next time.

Maxime B.
  • 1,026
  • 7
  • 20