Reputation: 8505
What is wrong in below
int data[2][2] = { {1,1}, {2,2}};
int sum = sum(data, 2);
Sum is defined as
int sum(int **data, int rows);
data contains the address of the data[0]
, so it can be treated as a pointer. The *data
leads me to the value, which is another array of type int
. This another array should be treated as pointer to first element. Hence why do compiler complains at the argument for int **data
?
I get a compiler error as show below. I understand the error, but my question is why **data
is not acceptable.
error: cannot convert int (*)[2] to int** for argument 1 to int sum(int**, int)
Upvotes: 1
Views: 4898
Reputation: 1327
int ** data
is a pointer to a pointer to an int
.
Passing data to sums first argument is actually just passing a int*
to it, which is not identical to int **
.
Further, once you're in sum()
, it has no idea that int **data
points to a 2 dimensional array, it just knows it's a pointer to a pointer to an int
...
Dereferencing data the first time gives you a pointer to an int
.
Dereferencing data the second time gives you the int
.
You'll need to change the interface to the sum()
function.
Upvotes: 0
Reputation: 26097
The array-name-to-pointer decay only happens once, so you get a pointer, not a pointer-to-a-pointer.
A C/C++ array is a contiguous allocation of data elements. An array of arrays is still a contiguous allocation of elements -- it's just that the elements are larger. This is what your error message "cannot convert int (*)[2] to int**
" is saying.
Another way to look at it: a double-dereference only works if it points to an array of pointers somewhere. However, C/C++ does not do this for you; you would need to allocate and fill one yourself.
The int (*)[2]
type is what allows you to access the array-of-arrays as data[i][j]
. If you want to access the array that way, you need to propagate that type everywhere it is used.
Upvotes: 0
Reputation: 19033
May be this helps:
int sum(int *i, int rows) {
cout << *i << *(i+1) << *(i+2) << *(i+3);
return 0;
}
int main() {
int data[2][2] = { {1,1}, {2,2}};
int sum1 = sum(data[0], 2);
return 0;
}
Upvotes: 1
Reputation: 24439
No matter if an array is one-dimensional or multi-dimensional, it can only be converted to pointer to the first element, and not to pointer to array of pointers.
To understand why, analyze how arrays are laid out in memory.
int data[3]
0.......4.......8...... (assume sizeof(int)==4)
data[0] data[1] data[2]
^ &data[0]
int data[3][2]
0..........4..........8..........12.........16.........20........
data[0][0] data[0][1] data[1][0] data[1][1] data[2][0] data[2][1]
^ &data[0][0]
All elements are always laid out linearly, so every array (one or multi-dimensional) is representable as pointer to the first element (arr[0][0]...[0]
), and only so. Multidimensional arrays can not be represented as pointer to array of pointers, because those arrays of pointers do not exist anywhere.
Dimensions are merely compile-time hints for translating into address (arr[i][j]
becomes *(array_memory + i*H + j)
). Pointer to pointer is entirely different structure than arrays; indexing it looks the same syntactically, but it causes entirely different thing to happen (ppi[i][j]
becomes *(*(ppi + i) + j)
.
Upvotes: 3
Reputation: 19445
int data[2][2] // It's basically array of 4 values. it's not array of arrays.
the dimentionals just explain the compiler how to access a value.
lets say you have:
data[R][C]
data[X][Y] == *(&data)[X*C + Y]
following this explanation, you should define you function:
int sum(int *data, int rows);
And if you want to show what it does, I may help you use it correctly.
Upvotes: 0
Reputation: 2857
You are supposed to include the size of the array in the definition of the parameters.
int sum(int data[2][2], int rows);
Note: If it was a dynamic array, then what you did before is right.
Upvotes: 2