0

In my main function, I allocate a 2D contiguous array with equal number of rows and columns that are decided by the user:

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

int main() {
int d=0;

scanf("%d", &d);

int(*matrix)[d]= malloc(d*sizeof(*matrix));

}

I then want to pass this matrix and the d value to a function that will fill it with numbers from 1 to d*d and then print it:

void fillMatrix(int d, /*matrix*/)

How should I pass the matrix to the function? I don't have trouble with the rest of the function per se, but I don't seem to be able to properly pass the matrix in order to then fill it as a generic 2d array with the line array[i][j]= value. From what CLion is telling me, I seem to be working wrong with the fact that it's a int(*)[d], as it often tells me that I'm passing an incompatible pointer when I try to actually call the function.

Some things I tried and didn't work:

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

void fillMatrix(int, int*);

int main() {
    int d=0;

    scanf("%d", &d);

    int(*matrix)[d]= malloc(d*sizeof(*matrix));

    fillMatrix(d, (int *) matrix);
}

void fillMatrix(int d, int *matrix){
    int i=0, j=0, k=1;

    for(i=0;i<d;i++){
        for(j=0;j<d;j++){
            matrix[i][j]= k;
            k++;
        }
    }
}

Here, when I try to do matrix[i][j]= k;, I get the error "Subscripted value is not an array, pointer, or vector ", and changing matrix to *matrix doesn't help

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

void fillMatrix(int, int*);

int main() {
    int d=0;

    scanf("%d", &d);

    int(*matrix)[d]= malloc(d*sizeof(*matrix));

    fillMatrix(d, matrix);
}

Here, when calling the function, I get the error "Incompatible pointer types passing 'int (*)[d]' to parameter of type 'int *' "

And when I try to write void fillMatrix(int, int[][]);, I get the error "Array has incomplete element type 'int []' "

Finally, if I do:

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

void fillMatrix(int, int[][0]);

int main() {
    int d=0;

    scanf("%d", &d);

    int(*matrix)[d]= malloc(d*sizeof(*matrix));

    fillMatrix(d, matrix);
}

void fillMatrix(int d, int matrix[][0]){
    int i=0, j=0, k=1;

    for(i=0;i<d;i++){
        for(j=0;j<d;j++){
            matrix[i][j]= k;
            k++;
        }
    }

    for(i=0;i<d;i++){
        for(j=0;j<d;j++){
            printf("%d ", matrix[i][j]);
        }

        printf("\n");
    }
}

it won't print the proper k value.

Lundin
  • 195,001
  • 40
  • 254
  • 396
Zhaxean
  • 3
  • 1

1 Answers1

1

The most correct form is this:

int(*matrix)[d][d] = malloc( sizeof(int[d][d]) );

Here it is pretty clear that we are declaring a pointer to a square 2D array of int. However, the reason why this form isn't often used is because de-referencing turns cumbersome: (*matrix)[i][j]. To skip this extra de-referencing, a handy trick is to drop one dimension out of the pointer declaration (and that's what your current code does too):

int(*matrix)[d] = malloc( sizeof(int[d][d]) );

Now we can do a readable matrix[i][j] as expected.

As for how to declare a function, just declare it as using a 2D array because that's what you want:

void fillMatrix (size_t size, int matrix[size][size]);

Now this decays to a pointer to the first element and what is the type of such a pointer? Since the first element is of type int [size] and a pointer to it is int(*)[size], we actually end up with the very same type as was used in main, 100% compatible.

Full example:

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

void fillMatrix (size_t size, int matrix[size][size])
{
  int k=1;

  for(size_t i=0; i<size; i++)
  {
    for(size_t j=0; j<size; j++)
    {
      matrix[i][j] = k++;
    }
  }
}

void printMatrix (size_t size, int matrix[size][size])
{
  for(size_t i=0; i<size; i++)
  {
    for(size_t j=0; j<size; j++)
    {
      printf("%2.d ", matrix[i][j]);
    }
    puts("");
  }
}

int main (void)
{
  size_t size=5;
  int(*matrix)[size] = malloc( sizeof(int[size][size]) );

  fillMatrix(size, matrix);
  printMatrix(size, matrix);
  
  free(matrix);
}

Further study: Correctly allocating multi-dimensional arrays

Lundin
  • 195,001
  • 40
  • 254
  • 396