0

I tried passing a 2D array to a function in C++ and I didn`t understand something:

//My array declaration:
int array[5][5]={{....}}; //I declared and filled the array with values
//My different function tries:
void passArr(int **array) //ERROR
void passArr(int *array[5]) //ERROR
void passArr(int *(*array)) //ERROR
void passArr(int (*(*array))) //ERROR
void passArr(int (*array)[5]) //WORKS

All errors were: [Error] cannot convert 'int (*)[5]' to 'int**' for argument '1' to 'void passArr(int**)'

Why do the errors show up and most importantly what is the difference between int *array[5] and int (*array)[5] when passing as an argument?

If int (*array)[5] worked, then why didn´t int *(*array) or int (*(*array))) also work?

  • One workaround around C++ type system would be to use a structure instead: `struct array5x5 { int data[5][5]; }; void passArr(array5x5 *array) { ... }`. Othewise, use C++ types like std::array, std::vector... You could also pass a reference to your array with something like `int (&array)[5][5]` – Phil1970 Apr 20 '21 at 01:29

4 Answers4

1

In C and C++, a 2D array is an Array-of-Arrays. The first element of a 2D array is the first 1D array it contains. The conversion is specified in C++ Standard - Array-to-pointer Conversion [conv.array]

When you declared a plain-old 2D array as:

int array[5][5]

You have an array of int[5] arrays. As with any array, it is converted to a pointer to its first element on access. The first element being an array of int[5], so the resulting type is:

int (*)[5]

A pointer-to-array-of int[5]. So for your 2D array named array, that is:

int (*array)[5]
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

They're just different things. Reading from right to left might be helpful.

int array[5][5]  -> array of array of int, could decay to pointer to array of int
int (*array)[5]  -> pointer to array of int, could be converted from the above

int **array      -> pointer to pointer to int
int *(*array)    -> same as above
int (*(*array))  -> same as above

int *array[5]    -> array of pointer to int
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • It's also important to know that C/C++ sometimes acts like a pointer to x is the same as an array of x but sometimes does not, e.g. in `struct X {int *x; int y[20]}` or `sizeof z`. – Jerry101 Apr 20 '21 at 01:00
0

Also, in the "C++" language, it is strongly advisable to use one of the very-many "container classes" for this purpose. Or perhaps a class of your own devising.

"A simple pointer" has no way to convey that it is pointing to "a 2D array," nor what its dimensions are. The extent of its job-description is that it knows how to point to "a bunch of bytes, or nothing."

But if instead you provided your caller with a reference to a class, your caller could now "ask the class" for what it needed, "and the class would magically know." Just hand the class (X,Y) and you either get the right answer or a runtime exception is thrown. Every single time ... and by the way, efficiently.

This is a much more-robust way to write code, and it really is the reason why the C++ language was invented.

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41
0

Versions 1,3, and 4 are all the same. Version 2 is also the same as 1,3, and 4, because when passing an array to a function the array decays to a pointer.

Version 2 can also be written

void passArr(int* array[5])

Which probably shows the association of the asterisk with the type more clearly: it is an array of five int-pointers. With the array decaying to a pointer, it becomes

void passArr(int** array)

All of them mean that the entry of the array are addresses, pointing to another array:

 [ * | * | * | * | * ]
   |    |    |    |   +-> [,,,,]
   |    |    |    +-> [,,,,]
And so on.

What you have is an array when each entry is an array of 5 ints, not a pointer to one (arrays bear a lot of resemblance with pointers, but they aren't pointers!)

Your matrix looks like this:

[ [1,2,3,4,5], [6,,,,], [,,,,], [,,,,], [,,,,] ]

So, array is a pointer to an int[5], not a pointer to pointer to int. And that is what the parentheses do in version 5: int (*array)[5]. This binds the asterisk closer to array.

Hernando Abella
  • 286
  • 2
  • 13