-2

i have this code but eclipse release error on return line but i know that int array[][] is same type by int **

int ** Master::what_can_choose()
{
array_can_choose[9][2]={0};
board[3][3]={{' ',' ','x'},{' ','o',' '},{'x',' ',' '}};
int x=0;
for (int i=0;i<3;i++)
{
    for (int j=0;j<3;j++)
    {
    if (board[i][j]==' ')
        {
        array_can_choose[x][0]=i;
        array_can_choose[x][1]=i;
        x+=1;
        }
    }
}
return array_can_choose;
}

why this error is released

error is: cannot convert `int (*)[2]' to `int**' in return
Kijewski
  • 25,517
  • 12
  • 101
  • 143

1 Answers1

3

First of all, an int** is not the same as an int[][]. If you're using an int** as a 2D-array with dynamic allocation, the internal structure is actually very different from a real 2D-array. Take a look at this code:

int** dynamic2DArray;
int static2DArray[10][10];

dynamic2DArray = new int*[10];
for( int i=0; i<10; i++ )
    dynamic2DArray[i] = new int[10];

Now, dynamic2DArray points to the first element in a list of 10 pointers which each point to a list of 10 ints, while static2DArray points to the first element in a list of 10*10=100 ints. So the structure in memory is completely different.

In addition, the following would also be a int**, while clearly having nothing to do with arrays:

int someInt;
int* pointerToSomeInt = &someInt;
int** doublePointerToSomeInt = &pointerToSomeInt;

A syntax error I spotted is that you're not declaring what type your arrays should be:

array_can_choose[9][2]={0};
board[3][3]={{' ',' ','x'},{' ','o',' '},{'x',' ',' '}};

Should be:

int array_can_choose[9][2]={0};
char board[3][3]={{' ',' ','x'},{' ','o',' '},{'x',' ',' '}};

This is because we don't just need to tell the compiler that we want an array, but also what it should be an array of. In this case, int and char.

Another problem with your code is that you're trying to return a local array. You can't do this. A local variable exists only so long as 'its name is known' (this is called 'being in scope'). In this case, the variable array_can_choose will cease to exist as soon as you exit from the function int ** Master::what_can_choose().

You may wonder why you can then ever return a variable from a function at all. This is because most variables can be copied. This is what happens when you return (for example) an int from a function, or when you pass an int into a function. However, arrays cannot be copied. This has been done to prevent immense unexpected slow-downs when copying very large arrays. Instead, when you pass an array into a function, you're only passing a variable which points to the contents of the array. This means that you cannot return a local array because the contents of this array will cease to exist when exiting the function. Therefor the return variable would point to 'not-existing' memory.

To circumvent this, you would have to use dynamic allocation:

int ** Master::what_can_choose()
{
    //dynamically allocate the array we want to return
    int** array_can_choose = new int*[9];
    for( int i=0; i<9; i++ )
    {
        array_can_choose[i] = new int[2];
        for( int j=0; j<2; j++ )
            array_can_choose[i][j] = 0; //initialize all values to 0
    }

    //a type (such as char) is required for arrays
    char board[3][3]={{' ',' ','x'},{' ','o',' '},{'x',' ',' '}};
    int x=0;
    for (int i=0;i<3;i++)
    {
        for (int j=0;j<3;j++)
        {
            if (board[i][j]==' ')
            {
                array_can_choose[x][0]=i;
                array_can_choose[x][1]=i;
                x+=1;
            }
        }
    }
    return array_can_choose;
}

Now, one drawback of using dynamic allocation is that you will also have to free the memory you allocated. Dynamic allocation ensures that memory will exist even when you leave the current scope (that's why we can now return our array), but this means it is no longer clear when the memory is allowed to 'stop existing'. Because of this, we explicitly need to tell the compiler when we're done with our memory, so that it can then free this memory. We can do this using delete[]. The []-part tells the compiler it should delete an entire array, not just one item. Because we allocated an array of arrays, we can't just do this deletion at once. We have to delete every sub-array and then the 2D-array itself (which, as explained before, is really a 1D-array of pointers to arrays).

Master master; //we need an object to call our function
int** our_array = master.what_can_choose(); //this allocates an array and stores it in our_array

//do stuff with our_array

for( int i=0; i<9; i++ )
    delete[] our_array[i]; //delete a sub-array
delete[] our_array; //delete the array itself.

//we can now no longer do stuff with our_array

Not deleting memory like this means that the memory we allocated will forever be occupied even if we don't need it any more, this is called a 'memory leak'. If you do this too often, your computer will eventually run out of memory and your program will crash.

JSQuareD
  • 4,641
  • 2
  • 18
  • 27