Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between ** and &** in C in context of 2D matrix

Tags:

c

pointers

matrix

I am working on a homework assignment to do matrix multiplication with dynamically allocated 2d arrays. I have written the following function to load the matrix:

void loadMatrix(FILE* fp, int** matrix, int rowSize, int colSize) {

    for (int i = 0; i < rowSize; i++) {
        for (int j = 0; j < colSize; j++) {
            fscanf(fp, "%d", &matrix[i][j]);
        }
    }
}

I declare my matrix as a global variable as follows:

int **a;

and then initialize and load it as follows:

// allocate memory for the array rows
a = (int **) malloc(m * sizeof(int*));

// allocate memory for array columns
for (int i = 0; i < m; i++) {
    a[i] = malloc(k * sizeof(int));
}

loadMatrix(fp, a, m, k);

Everything works as expected, however the function signature that the teacher provided is the following:

void loadMatrix(FILE*, int ***, int, int);

I tried using that signature, and pass in the address of the matrix using &, and removing the & from my loadMatrix function, thinking that the outputs should be the same, but using *** does not work as expected. What am I missing? Also what would be the advantage of using triple pointers if there is one?

like image 904
Luke LaFountaine Avatar asked Feb 22 '16 05:02

Luke LaFountaine


People also ask

Whats the difference between * and &?

The & is a unary operator in C which returns the memory address of the passed operand. This is also known as address of operator. <> The * is a unary operator which returns the value of object pointed by a pointer variable.

What is the difference between '/' and %' operator?

Solution. The / operator is used for division whereas % operator is used to find the remainder.

What is the difference between and ::?

The :: operator is known as the scope resolution operator, and it is used to get from a namespace or class to one of its members. The . and -> operators are for accessing an object instance's members, and only comes into play after creating an object instance.

Is there a difference between == and is?

== is for value equality. It's used to know if two objects have the same value. is is for reference equality. It's used to know if two references refer (or point) to the same object, i.e if they're identical.


1 Answers

Your code has the following problems:

  • You are not allocating 2D arrays, but rather pointer-to-pointer based look-up tables segmented all over the heap. This is widespread but poor practice: there is never a reason to segment your 2D array and allocate it in multiple places. The code turns complex and the program turns slow, for no benefit.

  • There is no reason to declare the matrix as a global variable.

  • There is never a reason to have 3 levels of indirection in C. This is known as "three star programming" and is a certain sign of fundamentally flawed program design. Unfortunately, this means that your teacher is not a trustworthy source of C knowledge.

Instead, you should be allocating 2D arrays:

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

void loadMatrix(FILE* fp, int rowSize, int colSize, int matrix[rowSize][colSize]) 
{
    for (int i = 0; i < rowSize; i++) {
        for (int j = 0; j < colSize; j++) {
            fscanf(fp, "%d", &matrix[i][j]);
        }
    }
}


int main (void)
{
  const int ROWS = 4;
  const int COLS = 5;
  int (*matrix)[ROWS][COLS]; // array pointer to variable-length array

  matrix = malloc( sizeof(int[ROWS][COLS]) );
  if(matrix == NULL)
  {
    // error handling
  }

  FILE* fp = ...;
  loadMatrix(fp, ROWS, COLS, *matrix); // contents of what the pointer points at is the array

  free(matrix);
}

To fully understand the above, I recommend studying variable-length arrays and how arrays decay into pointers to the first element.

like image 165
Lundin Avatar answered Oct 18 '22 05:10

Lundin