当我使用new []
来应用内存时。最后,我使用delete
释放内存(不是delete[]
)。这会导致内存泄漏吗?
两种类型:
int
,char
,double
... 我认为可能会泄漏。因为破坏功能。
很多人和一些书告诉我,new[]
- > delete[]
; new
- > delete
。
我想知道为什么。
所以我检查vs2010源代码,一定要使用内存池机制。它漫长而复杂。我不能继续阅读。
delete
和delete[]
如何实施?
答案 0 :(得分:4)
当我使用new []来应用内存时。最后,我使用delete来释放memeory(不是删除[])。必须是内存泄漏吗?
如果你使用new[]
,然后delete
(不是delete[]
),那么根据langauge规范,它会调用undefined-behavior,这意味着任何事情都可能发生。 可能导致内存泄漏或可能不会。语言和编译器都没有这样的保证。
很多人和一些书告诉我,new [] - > delete []; new->删除。我想知道为什么?
简短回答:因为规范是这样说的。
长答案:实现new
和new[]
的函数的实现方式不同:new
假设要分配一个项的内存,而new[]
假定{的内存为{ {1}}项将被分配,其中n
作为参数传递给函数。因此,为了撤消该过程(即释放内存),还应该有两个函数:n
和delete
,它们以不同的方式实现,每个函数都对它们的对应物分配的内存做出一些假设。例如,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 []会破坏每个元素,最后释放内存块。而删除将无法识别这样的结构。也许这是内存泄漏,也许你会得到一些例外。