我有这个代码,但在返回行上有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
答案 0 :(得分:3)
首先,int**
与int[][]
不同。如果您使用int**
作为具有动态分配的2D数组,则内部结构实际上与实际2D数组非常不同。看看这段代码:
int** dynamic2DArray;
int static2DArray[10][10];
dynamic2DArray = new int*[10];
for( int i=0; i<10; i++ )
dynamic2DArray[i] = new int[10];
现在,dynamic2DArray
指向10个指针列表中的第一个元素,每个指针指向10个int
的列表,而static2DArray
指向列表中的第一个元素10 * 10 = 100 int
s。所以内存中的结构完全不同。
此外,以下也是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
时,或者将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[]
执行此操作。 []
- 部分告诉编译器它应该删除整个数组,而不仅仅是一个项目。因为我们分配了一个数组数组,所以我们不能一次完成这个删除。我们必须删除每个子数组,然后删除2D数组本身(如前所述,它实际上是一个指向数组的指针的一维数组)。
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
不删除这样的内存意味着我们分配的内存将永远被占用,即使我们不再需要它,这称为'内存泄漏'。如果您经常这样做,您的计算机最终将耗尽内存,程序将崩溃。