Reputation: 4687
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
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
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
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
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 int
s. 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
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
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