为什么“删除[] [] ...... multiDimensionalArray;” C ++中的operator不存在

时间:2008-10-13 15:48:01

标签: c++ arrays

我一直想知道是否有用于删除标准C ++语言中的多维数组的运算符。

如果我们创建了一个指向单维数组的指针

int *array = new int[size];

删除看起来像:

delete [] array;

那很好。但是如果我们有二维数组,我们就不能做

delete [][] twoDimenstionalArray;

相反,我们应该循环并删除项目,例如this示例。

有人可以解释原因吗?

9 个答案:

答案 0 :(得分:25)

从技术上讲,C ++中没有二维数组。您作为二维数组使用的是一维数组,每个元素都是一维数组。由于技术上不存在,C ++无法删除它。

答案 1 :(得分:20)

因为无法打电话

int **array = new int[dim1][dim2];

所有新闻/删除都必须平衡,因此delete [][]运营商没有意义。

new int[dim1][dim2]返回指向类型为dim1的大小为int[dim2]的数组的指针。所以dim2必须是编译时常量。这类似于在堆栈上分配多维数组。

答案 2 :(得分:7)

在该示例中多次调用delete的原因是因为new也被多次调用。必须为每个新人调用删除。

例如,如果我分配1,000,000字节的内存,我以后不能删除200,000 - 300,00中的条目,它被分配为一个整块,必须作为一个整块释放。

答案 3 :(得分:6)

你必须循环的原因,就像你提到的例子一样,编译器/分配器不知道需要删除的数组的数量。

当您分配二维数组时,您确实创建了N个一维数组。现在每个都必须删除,但系统不知道有多少。顶级数组的大小,即指向二级数组的指针数组,就像C中的任何其他数组一样:它的大小不会被系统存储。

因此,无法按照您的描述实施delete [][](不会显着改变语言)。

答案 4 :(得分:4)

从语言设计的角度来看,我不确定确切的原因,我猜这与事实有关,即在分配内存时你要创建一个数组数组,每个数组都需要删除。

int ** mArr = new int*[10];
for(int i=0;i<10;i++)
{
   mArr[i]=new int[10];
}

我的c ++生锈了,我不确定这在语法上是否正确,但我认为它很接近。

答案 5 :(得分:3)

虽然所有这些答案都是相关的,但我会尝试解释什么是期望的,像 delete[][] array; 这样的东西可能对动态分配的数组起作用,为什么它不可能:

静态分配的数组所允许的语法int array[ROWS][COLS];只是程序员的抽象,实际上它创建了一维数组int array[ROWS*COLS];。但是在编译过程中(当维度大小COLSROWS必须是标准的常量时),编译器还会记住这些维度的大小,这些维度是稍后使用语法解决元素所必需的。 array[x][y] = 45。然后,编译器以此大小知道,将使用简单的数学运算将[x][y]替换为对应的一维数组索引:[COLS*x + y]

另一方面,如果您想要相同的多维功能(实际上是表示法),则动态分配的数组不是这种情况。由于它们的大小可以在运行时确定,因此它们必须记住每个附加维度的大小以供以后使用 - 并记住在数组的整个生命周期中。此外,系统更改必须在这里实现,以实际上作为多维使用数组,在代码中保留[x][y]访问符号的形式,而不是在编译期间用一维符号替换它,但后来替换它在运行时间内。

因此 array = new int[ROWS][COLS] 缺席意味着没有必要 delete[][] array; 。并且如前所述,它不能用于您的示例中删除“多维”数组,因为您的子数组(其他维度)是单独分配的(使用单独的new调用),因此它们是独立于包含它们的顶部数组(array_2D),它们都不能一次删除。

答案 6 :(得分:0)

delete []适用于任何非标量(数组)。

答案 7 :(得分:0)

您可以使用包装器类为您执行所有这些操作。 使用“原始”数据类型通常不是一个好的解决方案(数组应该封装在一个类中)。例如,std :: vector就是一个非常好的例子。

删除应该被称为新调用的次数。因为你不能称之为“a = new X [a] [b]”,你也不能称之为“删除[] []一个”。

从技术上讲,这是一个很好的设计决策,可以防止出现整个n维矩阵的奇怪初始化。

答案 8 :(得分:0)

嗯,我觉得它很容易实现,但太危险了。很容易判断指针是否由new[]创建,但很难说明new[]...[](如果允许)。