2

I have to call a function which passes 2d array as argument. Function call:

    int n;
    char ch;
    cin>>n;
    bool b[n][n];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            if(ch=='X'){b[i][j]=1;}  //reads input from a file
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cout<<evaluate(n,b, i,  j);  //shows error no matching function for call to evaluate
        }
        cout<<endl;
    }

However,it displays an error no matching function to the call Here's my function evaluate's declaration:

int evaluate(int n,bool** b,int x,int y){
  //body
}

I have tried variations in function declaration as:evaluate(int n,bool b[n][n],int x,int y); but it gives the same error. Also on removing the 2d array argument,the function works. Please suggest what my mistake is.

code_enthu
  • 143
  • 1
  • 3
  • 13
  • possible duplicate of [passing 2D array to function](http://stackoverflow.com/questions/8767166/passing-2d-array-to-function) – user1781290 Jun 28 '14 at 07:32
  • Thanks @user1781290 for the thread. I did search,but couldn't find this post, you suggested ,earlier. Also thanks for all the other answers. – code_enthu Jun 29 '14 at 07:50

3 Answers3

3

Array names converted to pointer to first element of array when passed to a function. A 2D array is a 1D array having all its elements of type 1D array, i.e it is an array of arrays.

When 2D array name passed to a function then it decays to pointer to first element of the array. As explained above, the element itself is a 1D array, therefore the type of array name becomes pointer to array.
pointer to array and pointer to pointer both are of different types (incompatible with each other). To pass a pointer to array type, you need to declare your function as

 int evaluate(int n, bool (*b)[n], int x, int y);  

or simply

 int evaluate(int n, bool b[][n], int x, int y);
haccks
  • 97,141
  • 23
  • 153
  • 244
1

What you need to understand is that a 2D array (a variable declared as int foo[m][n];) is something very different from a double pointer (a variable of type int **foo;). Even though you may use foo[i][j] in both cases, what happens is radically different:

  • In the case of a 2D array, foo[i][j] is effectively evaluated as foo[i*m + j], all the lines of the 2D array are contiguous in memory, and there is no index structure.

  • In the case of a double pointer, foo[i][j] first loads a pointer from memory at foo[i], then it loads an int from behind that loaded pointer. That is, foo must point to an array of pointers, that indices into the different line arrays. The line arrays may be independent of each other, they are connected via the index array.

Consequently, you cannot just pass a 2D array as an int** to a function since there is no index array in the 2D array.

However, you can pass a pointer to an array (pseudocode, I omitted declaring some variables):

const int width = ...;

void foo(int (*twoDArray)[width], int x, int y) {
    //do something with twoDArray[x][y]
}

int main() {
    int myArray[height][width];
    foo(myArray, x, y);
}

Unfortunately, width has to be a compile time constant in C++. C can handle dynamic array size, C++ cannot. This severely limits the usability of this approach.

cmaster - reinstate monica
  • 33,875
  • 7
  • 50
  • 100
-2

Do you defined your function (callee) before main (caller) function? you should do like this:

int evaluate(int n,bool** b,int x,int y);

int main(){
    //some code
    evaluate(n, b, i, j);
    //some code
}

int evaluate(int n,bool** b,int x,int y){
    //body
}

or this way:

int evaluate(int n,bool** b,int x,int y){
    //body
}

int main(){
    //some code
    evaluate(n, b, i, j);
    //some code
}