如何实现删除和删除[]?

时间:2012-03-25 07:46:21

标签: c++ memory-management new-operator

当我使用new []来应用内存时。最后,我使用delete释放内存(不是delete[])。这会导致内存泄漏吗?

两种类型:

  1. 内置类型,例如intchardouble ...
    我不确定。
  2. 班级类型。
  3. 我认为可能会泄漏。因为破坏功能。

    很多人和一些书告诉我,new[] - > delete[]; new - > delete。 我想知道为什么。 所以我检查vs2010源代码,一定要使用内存池机制。它漫长而复杂。我不能继续阅读。

    deletedelete[]如何实施?

4 个答案:

答案 0 :(得分:4)

  

当我使用new []来应用内存时。最后,我使用delete来释放memeory(不是删除[])。必须是内存泄漏吗?

如果你使用new[],然后delete(不是delete[]),那么根据langauge规范,它会调用undefined-behavior,这意味着任何事情都可能发生。 可能导致内存泄漏或可能不会。语言和编译器都没有这样的保证。

  

很多人和一些书告诉我,new [] - > delete []; new->删除。我想知道为什么?

简短回答:因为规范是这样说的。

长答案:实现newnew[]的函数的实现方式不同:new假设要分配一个项的内存,而new[]假定{的内存为{ {1}}项将被分配,其中n作为参数传递给函数。因此,为了撤消该过程(即释放内存),还应该有两个函数:ndelete,它们以不同的方式实现,每个函数都对它们的对应物分配的内存做出一些假设。例如,delete[]只是假设为一个项目分配的内存将被释放;另一方面,delete需要知道要释放内存的项目数,因此它假定delete[] number 项存储在分配的内存中的某处,最常见的是在分配的内存的开始,因此new[]首先读取存储项目数的内存部分,然后相应地释放内存。

请注意,delete[]new各自调用默认构造函数来构造已分配内存中的对象,new[]delete调用析构函数进行破坏解除分配内存之前的对象。

答案 1 :(得分:4)

这不是内存泄漏;这是未定义的行为。那更糟糕。

delete分配的内存上调用new[]可能会导致堆损坏,从而导致应用程序崩溃。当然不是立刻,因为那太有用了。它会在堆被破坏很久之后很久才会崩溃,几乎无法追踪。

始终将delete[]new[]一起使用。实际上,从不使用new[] 开头。除非您有特殊和特殊的需求,否则请使用std::vector

  

我想知道为什么?

为什么重要?这是错误并导致程序损坏。这是错误的,因为C ++标准是这样说的。

但是,如果你坚持理由......

请注意,您可以使用new[]分配任意数量的项目。你可以把任何计数数字(也就是:正整数)放在那里。因此,您可以new int[50]new int[someIntegerVariable]。这一切都很好。

另请注意,delete[] 需要计算。嗯......这怎么可能?如果你分配50 int s,显然delete需要知道你分配了多少,对吧?但你不必告诉它;它自动地知道。

如何?因为new int[50]分配更多而不仅仅是50 int的数组。它还分配足够的空间来保持分配的大小。可以把它想象为分配51 int但只允许你使用其中的50个。

然后,delete[]出现了。它找出了new[]分配的计数的位置。并且它使用该计数来释放内存。

delete 执行此操作。因此,无法正确释放内存。

答案 2 :(得分:1)

Nawaz是正确的,因为规范是这样说的。

它背后的实现原因是当你调用delete时,编译器会在释放内存之前添加对该对象的析构函数的调用。

对于数组,对析构函数的调用次数取决于分配的对象数,这些对象仅在运行时已知。因此,new[]可以保存有关delete[]使用的对象数量的额外信息。

使用new / delete时,不需要此信息。

答案 3 :(得分:0)

你不应该这样做。但是,对于大多数实现,只要数组的元素类型没有析构函数,就可以安全地删除带有delete而不是delete [],的数组。

对于带析构函数的类型,new []必须在动态分配的内存块中的某处记录数组的长度。 delete []会破坏每个元素,最后释放内存块。而删除将无法识别这样的结构。也许这是内存泄漏,也许你会得到一些例外。