【问题标题】:delete[] vs delete in a for loop [duplicate]删除 [] 与 for 循环中的删除 [重复]
【发布时间】:2013-09-26 05:10:48
【问题描述】:

做有什么区别:

int* I = new int[100];
for (int J = 0; J < 100; ++J)
{
    delete I++;
}

//and

int* I = new int[100];
delete[] I;

我知道第一个是错误的。我知道如何正确使用 delete[] 与 delete。 我只是想知道为什么这些有什么不同。就像在循环中找出 delete[] 和 delete 之间的真正区别一样。那么有什么区别呢?

【问题讨论】:

  • delete[] 和 delete 的行为不同,所以这就像是在问为什么 a++ 和 a-- 不同。

标签: c++


【解决方案1】:

newdelete 的两个版本都有两个任务:分配/释放和构造/销毁。

  • new 将分配内存并调用构造函数。

  • delete 将调用解构函数并释放内存。

  • new [] 分配单个内存块,然后可能多次调用构造函数。

  • delete [] 可能多次调用解构器,然后释放一块内存。

因此,多次使用delete 意味着释放多个内存块,而使用delete[] 将释放单个内存块;多次使用delete 不等于使用delete []

【讨论】:

    【解决方案2】:

    不同之处在于,首先,您删除的是您没有从new 取回的指针。

    【讨论】:

      【解决方案3】:

      没有可比性

      对所有news 使用deletes

      delete []s 对于所有new []s

      第一个只是删除不是来自new的指针

      【讨论】:

        【解决方案4】:

        当您使用new Foo[n] 时,您正在为一块足够大的内存进行一次分配,以容纳n 类型为Foo 的连续元素的数组。这与分配n 的连续内存块不同,每个Foo 一个。

        从内存分配器的角度来看,它实际上只是一个大的分配。当您执行delete arraydelete (array + 42) 时,基本上会要求内存分配器删除包含特定项目的大分配部分,这是它无法做到的。这就像尝试通过执行 delete (&amp;(new Foo())-&gt;bar) 来释放新对象的单个成员 - 对象的其余部分会发生什么?

        即使在单元素数组上,delete array 也不起作用,因为分配器对数组和单个对象使用不同的簿记逻辑(例如,存储数组中元素的数量)。因此,您确实必须将delete[]new[]deletenew 一起使用。

        【讨论】:

          【解决方案5】:

          这是声明一个整数数组:

          int* I = new int[100];
          

          这是遍历整数数组并尝试删除它们:

          for (int J = 0; J < 100; ++J)
          {
              delete I++; // bad
          }
          

          这是删除整数数组:

          delete [] I; // correct
          

          由于您使用[] 分配了数组,因此您使用[] 取消分配它。如果没有[],您不会释放使用[] 分配的内存。

          【讨论】:

            【解决方案6】:

            delete 和 delete[] 的区别在于 delete 会调用一个对象的析构函数,而 delete[] 会调用数组中每个对象的析构函数。在整数的情况下,差异并不明显,但如果你在析构函数中有任何影响,你会遇到问题,因为你不会正确地销毁所有对象。

            也就是说,对于简单类型,您仍然不应该使用 delete 而不是 delete[],因为两个运算符的编译代码可能不同(例如,delete[] 可能期望将整数存储在与表示要删除的对象数量的数组)。所以,一般规则是如果你使用 new,总是使用 delete,如果你使用 new[],总是使用 delete[]。

            【讨论】:

            • 嗯,这里的区别 很明显:对数组中的每个元素调用 delete 将导致 99 个无效的 frees。
            • 正确。我的意思只是 int 的“析构函数”并没有真正做任何事情,也没有真正解决正确释放内存的问题。
            【解决方案7】:

            第一个示例产生未定义的行为,因为纯删除表达式(与 delete[] 相对)只能应用于以下任一操作数:

            • 一个空指针值
            • 指向由前一个新表达式创建的非数组对象的指针
            • 或指向子对象的指针

            对使用 new[] 分配的数组的单个元素调用 delete 不属于这些类别中的任何一个,因为您的数组元素是非数组对象,没有使用单独的 new 表达式创建。

            (C++ 标准 5.3.5)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-03-14
              • 2023-01-25
              • 1970-01-01
              • 2017-04-17
              • 1970-01-01
              • 2016-04-25
              • 1970-01-01
              • 2011-05-14
              相关资源
              最近更新 更多