Jeff Nama
Jeff Nama

Reputation: 61

Dynamic array swaps columns and rows when passed by reference

I have following code with methods to:

  1. create a matrix
  2. print it
  3. add two matrices
#include <stdio.h>
#include <stdlib.h>

#define VECTOR_ROWS 3
#define VECTOR_COLS 1

void add_matrix(double***, double**, int, int);
void print_matrix(double**, int, int);
double** new_matrix(int, int);

int main() {
    
    printf("First vector:\n");
    double **vector = new_matrix(VECTOR_ROWS, VECTOR_COLS);
    print_matrix(vector, VECTOR_ROWS, VECTOR_COLS);
    
    printf("\nSecond vector:\n");
    double **vector2 = new_matrix(VECTOR_ROWS, VECTOR_COLS);
    print_matrix(vector2, VECTOR_ROWS, VECTOR_COLS);
    
    printf("\nAdd vector:\n");
    add_matrix(&vector, vector2, VECTOR_ROWS, VECTOR_COLS);
    print_matrix(vector, VECTOR_ROWS, VECTOR_COLS);
    
    return 0;
}

void add_matrix(double*** matrix, double** trans_matrix, int rows, int cols)
{
    int r, c;
    
    for (r = 0; r < rows; r++)
        for (c = 0; c < cols; c++)
            *matrix[c][r] += trans_matrix[r][c];        // WHY DOES IT WORK THIS WAY?   
    
}

double** new_matrix(int row, int col)
{
    double **matrix = (double**)malloc(row * sizeof(double*));
    int r, c;
    
    for(r = 0; r < row; r++)
        matrix[r] = (double*)malloc(col * sizeof(double));
    
    for (r = 0; r < row; r++)
        for (c = 0; c < col; c++)
            scanf("%lf", &matrix[r][c]);
    
    return matrix;
}

void print_matrix(double** matrix, int rowCount, int colCount)
{
    int r, c;
    
    for (r = 0; r < rowCount; r++)
    {
        for (c = 0; c < colCount; c++)
            printf("%lf ", matrix[r][c]);
        printf("\n");
    }
}

Basically, I create vector and vector2 and attempt to add them. It only works if the first matrix in add_matrix(...) has the [r][c] swapped, as if because I passed it by reference, its rows and columns swapped. If I reference it with [r][c], I get a sef fault, but this works and I have no clue why.

Upvotes: 2

Views: 211

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

The left operand in this assignment

*matrix[c][r] += trans_matrix[r][c];

is incorrect.

That is the left operand is equivalent to

*( matrix[c][r] )

Write

( *matrix )[r][c] += trans_matrix[r][c];

or

matrix[0][r][c] += trans_matrix[r][c];

Actually there is no sense to pass the pointer to the first matrix by reference because the pointer itself is not changed within the function.

The function could be declared like

void add_matrix(double** matrix, double** trans_matrix, int rows, int cols);

Upvotes: 3

Related Questions