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?
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.
Solution. The / operator is used for division whereas % operator is used to find the remainder.
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 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With