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
  • 49,934
  • 160
  • 51
  • 83
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,116
  • 8
  • 21
  • I had written '#include ' in the original code(and in the question also), it was just not displayed when I typeset the question for the first time. – Martund Mar 19 '20 at 09:34
  • Don't be a three star C programmer. **Return** the allocated pointer from your function. – n. m. could be an AI Mar 19 '20 at 09:35
  • That's fine. I edit my post, see the other issue, which is the main one. – Maxime B. Mar 19 '20 at 09:36
  • @n.'pronouns'm. Both method are highly similar tbh. Also, I've shown both ways, which is the best to understand pointers imho. – Maxime B. Mar 19 '20 at 09:42
  • @MaximeB., in the last code, we are returning mat which is a pointer to pointer, and the return type of this function is int. – Martund Mar 19 '20 at 09:44
  • Thank you very much, I was confused in this. – Martund Mar 19 '20 at 09:49
  • @MaximeB. The second variant is **bad**, it should not receive `mat` as a parameter. `malloc` does not receive the pointer as a parameter. Why does your function? See the other answer for a better example. – n. m. could be an AI Mar 19 '20 at 11:36