【问题标题】:Why "delete [][]... multiDimensionalArray;" operator in C++ does not exist为什么“删除[][]...多维数组;” C++ 中的运算符不存在
【发布时间】:2010-09-16 22:01:08
【问题描述】:

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

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

int *array = new int[size];

删除看起来像:

delete [] array;

那太好了。但是如果我们有二维数组,我们就不行了

delete [][] twoDimenstionalArray;

相反,我们应该循环并删除项目,就像在this 示例中一样。

谁能解释一下原因?

【问题讨论】:

    标签: c++ arrays


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      因为没有办法调用

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

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

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

      【讨论】:

      • 情况正好相反。 dim2 必须是编译时间常数,而 dim1 不需要,并且返回一个 int()[dim2] :) 想象一下如果执行 int v[dim1] 会发生什么,您可以记住语法[暗淡2];并检查 v 衰减到指针后的类型:它是 int()[dim2];
      【解决方案3】:

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

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

      【讨论】:

      • 因此相反的情况也是如此,如果它被分配为多个块,它必须被释放为多个块
      【解决方案4】:

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

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

      因此,无法按照您的描述实现delete [][](无需显着更改语言)。

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

          虽然所有这些答案都是相关的,但我将尝试解释预期的结果,像 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),它们都不能一次删除。

          【讨论】:

            【解决方案7】:

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

            【讨论】:

            • 不,如果你试图删除[]一个锯齿状数组,你会导致内存泄漏。
            【解决方案8】:

            您可以使用包装类来为您完成所有这些事情。 使用“原始”数据类型通常不是一个好的解决方案(数组应该封装在一个类中)。例如 std::vector 就是一个很好的例子。

            delete 应该准确地被调用多少次 new 被调用。因为不能调用“a = new X[a][b]”,所以也不能调用“delete [][]a”。

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-05-15
                • 1970-01-01
                • 1970-01-01
                • 2017-12-19
                • 2021-08-08
                • 1970-01-01
                • 2021-09-05
                • 1970-01-01
                相关资源
                最近更新 更多