-2

我有这个代码,但返回线上的 Eclipse 发布错误,但我知道 int array[][] 与 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;
}

为什么这个错误被释放

error is: cannot convert `int (*)[2]' to `int**' in return
4

1 回答 1

3

首先, anint**与 an 不同int[][]。如果您将 anint**用作具有动态分配的二维数组,则内部结构实际上与真正的二维数组非常不同。看看这段代码:

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

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

现在,dynamic2DArray指向 10 个指针列表中的第一个元素,每个指针指向 10int秒的列表,同时static2DArray指向 10*10=100int秒的列表中的第一个元素。所以内存中的结构是完全不同的。

此外,以下也将是 a int**,而显然与数组无关:

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

我发现的一个语法错误是你没有声明你的数组应该是什么类型:

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

应该:

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

这是因为我们不仅需要告诉编译器我们想要一个数组,还需要告诉编译器它应该是一个数组。在这种情况下,intchar

您的代码的另一个问题是您试图返回一个本地数组。你不能这样做。一个局部变量只存在于“它的名字是已知的”(这被称为“在范围内”)。array_can_choose在这种情况下,一旦您退出函数,该变量将不复存在int ** Master::what_can_choose()

你可能想知道为什么你可以从一个函数中返回一个变量。这是因为大多数变量都可以复制。当您int从函数返回(例如) an 或将 an 传递给函数时,就会发生这种情况int。但是,不能复制数组。这样做是为了防止在复制非常大的数组时出现巨大的意外减速。相反,当您将数组传递给函数时,您只是传递了一个指向数组内容的变量。这意味着您不能返回本地数组,因为退出函数时该数组的内容将不复存在。因此,返回变量将指向“不存在”的内存。

为了避免这种情况,您必须使用动态分配:

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;
}

现在,使用动态分配的一个缺点是您还必须释放分配的内存。动态分配确保即使您离开当前范围时内存仍会存在(这就是我们现在可以返回数组的原因),但这意味着何时允许内存“停止存在”不再明确。正因为如此,当我们用完我们的内存时,我们需要明确地告诉编译器,以便它可以释放这些内存。我们可以使用delete[]. -part[]告诉编译器它应该删除整个数组,而不仅仅是一个项目。因为我们分配了一个数组数组,所以我们不能一次删除。我们必须删除每个子数组,然后删除 2D 数组本身(如前所述,它实际上是指向数组的指针的 1D 数组)。

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

不这样删除内存意味着我们分配的内存将永远被占用,即使我们不再需要它,这称为“内存泄漏”。如果您经常这样做,您的计算机最终将耗尽内存并且您的程序将崩溃。

于 2013-03-17T15:46:11.933 回答