首先, 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',' ',' '}};
这是因为我们不仅需要告诉编译器我们想要一个数组,还需要告诉编译器它应该是一个数组。在这种情况下,int
和char
。
您的代码的另一个问题是您试图返回一个本地数组。你不能这样做。一个局部变量只存在于“它的名字是已知的”(这被称为“在范围内”)。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
不这样删除内存意味着我们分配的内存将永远被占用,即使我们不再需要它,这称为“内存泄漏”。如果您经常这样做,您的计算机最终将耗尽内存并且您的程序将崩溃。