调试c ++代码或eclipse中的错误

时间:2013-03-17 15:18:23

标签: c++

我有这个代码,但在返回行上有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

1 个答案:

答案 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',' ',' '}};

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

您的代码的另一个问题是您正在尝试返回本地数组。你不能这样做。局部变量只有在“其名称已知”时才存在(这称为“在范围内”)。在这种情况下,一旦退出函数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

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