Frustrated Coder
Frustrated Coder

Reputation: 4687

Passing array as a parameter

I read in a book that, int f (int P[2][4]) cannot accept A[2][3], but B[3][4] is fine. what is the reason for this? Especially when we create dynamic allocation using pointers, this should not be a problem. Thanks

Upvotes: 4

Views: 351

Answers (6)

Aviv A.
Aviv A.

Reputation: 697

The second parameter define the 2d array type since it's differs how many elements will be in every column.

The first parameter is only define the size of the array, and since you can send longer array to that function, it's like passing parameter with type: int*[3] which is similar to passing 1d array with size 10 to function that expect to get array with shorter size - and this is legal in c++.

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361254

The reason why it's not allowed, because f(int P[2][4]) becomes f(int (*P)[4]) so you can pass int B[3][4] which can decay into int (*B)[4], but int A[2][3] cannot decay into int (*A)[4], so the latter will not be accepted by f(int (*P)[4]).

The type int (*)[3] is incompatible with int (*)[4]. One cannot convert to the other!

However there is a solution. You can do this:

 template<size_t M, size_t N>
 int f(int (&P)[M][N])
 {
      //Use M and N as dimensions of the 2D array!
 }

 //Usage
 int A[2][3];
 f(A); //M becomes 2, N becomes 3

 int  B[3][4];
 f(B); //M becomes 3, N becomes 4

It will accept all two dimensional arrays!

Upvotes: 1

Eelke
Eelke

Reputation: 21993

It has todo with the memory layout. The first number is basically your number of rows and the second is how many elements are in each row. Rows are placed directly after each other. So there offset is determined by the number of elements in the rows multiplied by the number of rows preceding. The compiled function will be calculating row offsets based on 4 elements. When you pass an array with another row length these calculations will be wrong.

Upvotes: 1

aschepler
aschepler

Reputation: 72271

The reason is that function parameters never really have array type. The compiler treats the declaration

int f(int P[2][4]);

as though it really said

int f(int (*P)[4]);

P is a pointer to an array of four ints. The type int [3][4] decays to that same type. But the type int [2][3] decays to the type int (*)[3] instead, which is not compatible.

Dynamic allocation is another matter entirely, and it probably does not involve array-of-array types no matter how you do it. (Array of pointers, more likely.)

Upvotes: 4

wkl
wkl

Reputation: 79893

In C and C++, if you specify a function takes 2-D arrays, then it has to be given an explicit column size (the second []). The row size (first []) is optional.

Upvotes: 1

James Kanze
James Kanze

Reputation: 153899

The reason is that int f( int P[2][4] ); is a synonym for int f( int (*P)[4] ); The first dimension in a function declaration is just comments.

Upvotes: 5

Related Questions