Jimm
Jimm

Reputation: 8505

c++ two dimensional array definition

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

Answers (6)

Ross
Ross

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

comingstorm
comingstorm

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

Yola
Yola

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

hamstergene
hamstergene

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

Roee Gavirel
Roee Gavirel

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

Jorge Aguirre
Jorge Aguirre

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

Related Questions