我一直想知道是否有用于删除标准C ++语言中的多维数组的运算符。
如果我们创建了一个指向单维数组的指针
int *array = new int[size];
删除看起来像:
delete [] array;
那很好。但是如果我们有二维数组,我们就不能做
delete [][] twoDimenstionalArray;
相反,我们应该循环并删除项目,例如this示例。
有人可以解释原因吗?
答案 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];
。但是在编译过程中(当维度大小COLS
和ROWS
必须是标准的常量时),编译器还会记住这些维度的大小,这些维度是稍后使用语法解决元素所必需的。 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[]...[]
(如果允许)。