richard
richard

Reputation: 309

What is the difference between array[ROWS][COLS] and **array

Why aren't these function prototypes equivalent?

void print_matrix(char *name, int SX, int SY, int m[SX][SY])

void print_matrix(char *name, int SX, int SY, int **m)

Upvotes: 1

Views: 190

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 477030

Even though the two function arguments can be consumed in the same way, namely via m[i][j], they're quite different:

  • int m[M][N] is an array of M arrays of N ints.

  • int **m is a pointer to a pointer to an int.

You cannot pass arrays as function arguments, so an "array of K elements of type T" decays to a "poin­ter-to-T", pointing to the first element of the array. Thus it is permissible and equivalent to write the first form as int m[][N] in a function argument, since the value M is lost. However, the value N is not lost; it is part of the type!

So the following are admissible/erroneous for the first form:

void f(int arr[M][N]);

int a[M][N];
int b[2*M][N];
int c[M][N + 1];

f(a);   // OK
f(b);   // OK; slowest extent is forgotten in the decay
//f(c); // Error! 'c' is not an array of {array of N ints}.

For the second form, the meaning is rather different:

void g(int **p);

int a;
int * pa = &a;

g(&pa);          // fine, pointer to 'pa'

int arr[M][N];

// g(arr);  // Error, makes no sense

The expression arr designates the pointer to the first element of an array of arrays of N integers, i.e. its type is int (*)[N]. Dereferencing it gives an array of N integers, and not a pointer to an integer.

There is no way to convert the expression arr into a pointer to a pointer: If you said,

int ** fool = (int**)arr;

then *fool would point to the first element of the first array (arr[0]), and not to an int pointer. So you cannot dereference the value further, because the value is not a pointer.

The only correct way to pass a two-dimensional array as a double pointer is to construct an intermediate helper array:

int * helper[M];   // array of pointers

for (size_t i = 0; i != M; ++i)
{
    helper[i] = arr[i]; // implicit decay
}

g(helper);  // or "g(&helper[0])"

Upvotes: 6

Related Questions