Narlok
Narlok

Reputation: 53

Passing matrix to function, C

Having looked around I've built a function that accepts a matrix and performs whatever it is I need on it, as follows:

float energycalc(float J, int **m, int row, int col){
...
}

Within the main the size of the array is defined and filled, however I cannot passs this to the function itself:

int matrix[row][col];
...
E=energycalc(J, matrix, row, col);

This results in a warning during compilation

"project.c:149: warning: passing argument 2 of ‘energycalc’ from incompatible pointer type project.c:53: note: expected ‘int **’ but argument is of type ‘int (*)[(long unsigned int)(col + -0x00000000000000001)]’

and leads to a segmentation fault.

Any help is greatly appreciated, thank you.

Upvotes: 3

Views: 5642

Answers (5)

Lundin
Lundin

Reputation: 215360

A pointer-to-pointer is not an array, nor does it point to a two-dimensional array. It has nothing to do with arrays, period, so just forget you ever heard about pointer-to-pointers and arrays together.

(The confusion likely comes from the hordes of confused would-be programming teachers/authors telling everyone that they should use pointer-to-pointer when allocating dynamic 2D arrays. Which is just plain bad advice, since it will not allocate a real array allocated in adjacent memory cells, but rather a fragmented look-up table exploded in pieces all over the heap. See this for reference about how to actually allocate such arrays.)

Assuming that your compiler isn't completely ancient, simply use a variable length array (VLA), which is a feature introduced in the C language with the C99 standard.

#include <stdio.h>

void print_matrix (size_t row, size_t col, int matrix[row][col]);


int main (void)
{
  int matrix[2][3] = 
  {
    {1,2,3},
    {4,5,6}
  };

  print_matrix(2, 3, matrix);

  return 0;
}

void print_matrix (size_t row, size_t col, int matrix[row][col])
{
  for(size_t r=0; r<row; r++)
  {
    for(size_t c=0; c<col; c++)
    {
      printf("%d ", matrix[r][c]);
    }
    printf("\n");
  }
}

Upvotes: -1

haccks
haccks

Reputation: 106142

Passing two dimensional array to a function in C is often confusing for newbies.
The reason is that they assume arrays are pointers and having lack of understanding how arrays decays to pointer.
Always remember that when passed as an argument arrays converted to the pointer to its first element.
In function call

E = energycalc(J, matrix, row, col);  

matrix is converted to pointer to its first element which is matrix[0]. It means that passing matrix is equivalent to passing &matrix[0]. Note that the type of &matrix[0] is int(*)[col] (pointer to an array of col int) and hence is of matrix. This suggest that the second parameter of function energycalc must be of type int(*)[col]. Change the function declaration to

 float energycalc(int col, int (*m)[col], int row, float J);  

and call your function as

 E = energycalc(col, matrix, row, J); 

Upvotes: 2

Spikatrix
Spikatrix

Reputation: 20252

If the array is declared as

int matrix[row][col];

then change the function declaration to

float energycalc(float J, int m[][col], int row, int col){

The name of a two dimensional array of type T does not decay to T**.

If col is a local variable, then you need to call the function with the col parameter before matrix. This is done so that col is visible in the function.

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 311186

The function should be declared like

float energycalc( float J, int row, int col, int ( *m )[col] );

if your compiler supports variable length arrays.

Otherwise if in declaration

int matrix[row][col];

col is some constant then the function can be declared the following way

float energycalc(float J, int m[][col], int row );

provided that constant col is defined before the function.

Your function declaration

float energycalc(float J, int **m, int row, int col);

is suitable when you have an array declared like

int * matrix[row];

and each element of the array is dynamically allocated like for example

for ( int i = 0; i < row; i++ ) matrix[i] = malloc( col * sizeof( int ) );

Upvotes: 3

Mateo Hrastnik
Mateo Hrastnik

Reputation: 553

I think you can do something like this in C

float function_name(int mat_width, int mat_height, float matrix[mat_width][mat_height]) {
    ... function body...
}

Upvotes: 0

Related Questions