Search code examples
cmemory-managementpass-by-referenceswapdynamic-arrays

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.


Solution

  • 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);