Home > OS >  Matrix Addition in C with pointers
Matrix Addition in C with pointers

Time:10-27

I am trying to add 2 matrices with pointers but only the first row is being computed properly. The second row, only row-1 computations are done. the rest of the matrix is just 0. I have tried malloc but then the entire resultant matrix is just 0.

Clarification : I have a working code for [i][j] method. However, I wanted to implement the same using pointers but unable to.


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define rng 10

int main (void)
{
    int selection,row,column,i,j;

    //Initial statements, input method selection and matrix dimension inputs
    printf("\n\tThis program performs addition of 2 matrices.");
    printf("\n\n\tThe matrix elements can be fed through a Random Number Generator or be fed by the user.");
    printf("\n\tPress 1 to initialise array with RNG values.");
    printf("\n\tPress 2 to initialise array with user fed values.");
    printf("\n\tSelection : ");
    scanf("%d",&selection);
    if(((selection==1)||(selection==2))==0)
    {
        printf("\n\tPlease make a valid selection next time. Closing GUI.\n");
        exit (0);
    }

    printf("\n\tPlease enter the matrix dimensions.\n");
    printf("\tPlease enter the number of rows : ");
    scanf("%d",&row);
    printf("\tPlease enter the number of columns : ");
    scanf("%d",&column);
    if(((row==0)||(column==0))==1)
    {
        printf("\n\tInvalid matrix dimensions. Closing GUI.\n");
        exit (0);
    }
    int matrix_1[row][column];
    int matrix_2[row][column];
    int matrix_3[row][column];              //Resultant Matrix

    //Matrix initialisation
    if(selection==1)
    {
        printf("\n\tA matrix with RNG values between 1 and %d will be generated.",rng);
        srand(time(NULL));
        for(i=0;i<row;i  )
        {
            for (j=0;j<column;j  )
            {
                matrix_1[i][j]=1 rand()%rng;
                matrix_2[i][j]=1 rand()%rng;
            }
        }
    }
    else
    {
        printf("\n\tPlease enter the matrix values.\n");
        printf("\n\tMatrix 1 : \n");
        for(i=0;i<row;i  )
        {
            for (j=0;j<column;j  )
            {
               printf("\tMatrix 1 [%d][%d] : ",i,j);
               scanf("%d",&matrix_1[i][j]);
            }
            printf("\n");
        }

        printf("\n\tMatrix 2 : \n");
        for(i=0;i<row;i  )
        {
            for (j=0;j<column;j  )
            {
               printf("\tMatrix 2 [%d][%d] : ",i,j);
               scanf("%d",&matrix_2[i][j]);
            }
            printf("\n");
        }
    }

    //Initialise matrix_3 aka resultant matrix
    for(i=0;i<row;i  )
        for (j=0;j<column;j  )
            matrix_3[i][j]=0;


    //Print the Matrices
    printf("\n\tMatrix 1 is : \n");
    for(i=0;i<row;i  )
    {
        for (j=0;j<column;j  )
        {
            printf("\t%d",matrix_1[i][j]);
        }
        printf("\n");
    }
    printf("\n\tMatrix 2 is : \n");
    for(i=0;i<row;i  )
    {
        for (j=0;j<column;j  )
        {
            printf("\t%d",matrix_2[i][j]);
        }
        printf("\n");
    }

    //Add the matrices
    int *loc_1=&matrix_1[0][0];
    int *loc_2=&matrix_2[0][0];
    int *loc_3=&matrix_3[0][0];

    for(i=0;i<row;i  )
    {
        for(j=0;j<column;j  )
        {
            *(loc_3 i j) = *(loc_1 i j)   *(loc_2 i j);
        }
    }

    //Print the resultant matrix
    printf("\n\tThe resultant matrix after addition is : \n");
    for(i=0;i<row;i  )
    {
        for (j=0;j<column;j  )
        {
            printf("\t%d",matrix_3[i][j]);
        }
        printf("\n");
    }

}

The output is like this :

val1 val2 val3 val4
val5 val6 val7 0
0     0    0   0
0     0    0   0

CodePudding user response:

Your code is attempting to access the 2D array (aka array of array) using a pointer to the first element of the 2D array. That is not standard compliant. Once i j is greater than or equal to column your code is illegal according to the standard.

However, on most systems it will work despite not being strictly standard compliant. But you have to multiply i with column to get the correct indexing. Like:

// NOT STANDARD COMPLIANT (but will work on most systems). NOT RECOMMENDED
*(loc_3 i*column j) = *(loc_1 i*column j)   *(loc_2 i*column j);

But why do something which isn't standard compliant when you can do it much simpler with compliant code? Just do:

matrix_3[i][j] = matrix_1[i][j]   matrix_2[i][j];

It's simple, compliant and doesn't require any extra variables.

It can also be written

*(*(matrix_3   i)   j) = *(*(matrix_1   i)   j)   *(*(matrix_2   i)   j);

but that's just making the code harder to read. So don't do it like that.

If you for some reason really want the extra variables, the correct syntax is:

int (*loc_1)[column] = matrix_1;

which makes loc_1 a pointer to an array of 'column' int.

CodePudding user response:

Matrix adding code is incorrect:

    int *loc_1=&matrix_1[0][0];
    int *loc_2=&matrix_2[0][0];
    int *loc_3=&matrix_3[0][0];

    for(i=0;i<row;i  )
    {
        for(j=0;j<column;j  )
        {
            *(loc_3 i j) = *(loc_1 i j)   *(loc_2 i j);
        }
    }

Operation *(loc_1 i j) is more or less equivalent to matrix_1[0][i j]. See following derivation

*(loc_1   i   j)                // loc_1 == &matrix[0][0]
*(&matrix[0][0]   i   j)        // matrix[0][0] == *(matrix[0]   0)
*(&*(matrix[0]   0)   i   j)    // &* cancel out
*(matrix[0]   0   i   j)
*(matrix[0]   i   j)
matrix[0][i   j]

Operation matrix_1[0][i j] is incorrect because:

  • it returns difference value from matrix_1[i][j]
  • invokes Undefined Behavior when i j >= columns

I assume that you have some very good reason to introduce loc_<n> variables rather than using matrix_<n>.

It should be:

int (*loc_1)[column] = matrix_1;
int (*loc_2)[column] = matrix_2;
int (*loc_3)[column] = matrix_3;

    for(i=0;i<row;i  )
    {
        for(j=0;j<column;j  )
        {
            loc_3[i][j] = loc_1[i][j]   loc_2[i][j];
        }
    }

Array matrix_1 of type int[row][column] decays to a pointer to its first element which is int[colums]. Therefore the expression matrix_1 can be assigned to a variable of type int(*)[column].

CodePudding user response:

This:

*(loc_3 i j) = *(loc_1 i j)   *(loc_2 i j);

is the part where you dereferenced the pointers wrong. Matrixes are saved in C as double arrays, first is the array of pointers that represent rows, and each pointer is pointing to an array of type you defined, in your case int that represents columns. So the correct way for this addition to work would be:

*(*(loc_3 i) j) = *(*(loc_1 i) j)   *(*(loc_2 i) j);

And variables should be defined as:

int **loc_1=matrix_1;
int **loc_2=matrix_2;
int **loc_3=matrix_3;

Edit: As comments pointed out the given answer is totaly wrong with given structures. To give this answer any point after using dynamic allocation for matrix_n the answer can work. So if this correction is made the code gives no error. Replacement for matrix_n definition:

//int matrix_1[row][column];
//int matrix_2[row][column];
//int matrix_3[row][column];              //Resultant Matrix
int **matrix_1;
int **matrix_2;
int **matrix_3;              //Resultant Matrix

matrix_1 = malloc(row * sizeof(int*));
matrix_2 = malloc(row * sizeof(int*));
matrix_3 = malloc(row * sizeof(int*));

for (i = 0; i < row; i  )
    matrix_1[i] = (int*)malloc(column * sizeof(int));
for (i = 0; i < row; i  )
    matrix_2[i] = (int*)malloc(column * sizeof(int));
for (i = 0; i < row; i  )
    matrix_3[i] = (int*)malloc(column * sizeof(int));

Edited the answer to fit the spirit of the question where it was asked how to add matrixes using pointers.

CodePudding user response:

Use functions and pointers to arrays.

void addMatrix(size_t cols, size_t rows, int (*m1)[cols], int (*m2)[cols], int (*result)[cols])
{
    for(size_t row = 0; row < rows; row  )
    {
        for(size_t col = 0; col < cols; col  )
            result[row][col] = m1[row][col]   m2[row][col];
    }
}

void *allocMatrix(size_t rows, size_t cols)
{
    int (*matrix)[rows][cols];
    return malloc(sizeof(*matrix)); //lets compiler do the math
}
  •  Tags:  
  • c
  • Related