将 new[] 与 delete 配对怎么可能只导致内存泄漏?

首先,根据 C++ 标准,对任何用 new[] 分配的东西使用 delete 是未定义的行为.

First of all, using delete for anything allocated with new[] is undefined behaviour according to C++ standard.

在 Visual C++ 7 中,这种配对会导致两种后果之一.

In Visual C++ 7 such pairing can lead to one of the two consequences.

如果类型 new[]'ed 有简单的构造函数和析构函数 VC++ 简单地使用 new 而不是 new[] 并使用 delete该块工作正常 - new 只调用分配内存",delete 只调用空闲内存".

If the type new[]'ed has trivial constructor and destructor VC++ simply uses new instead of new[] and using delete for that block works fine - new just calls "allocate memory", delete just calls "free memory".

如果类型 new[]'ed 有一个非平凡的构造函数或析构函数,则上述技巧无法完成 - VC++7 必须准确调用正确数量的析构函数.所以它在数组前面加上一个 size_t 来存储元素的数量.现在 new[] 返回的地址指向第一个元素,而不是块的开头.因此,如果使用 delete ,它只会调用第一个元素的析构函数,并且调用空闲内存"的地址与分配内存"返回的地址不同,这会导致 HeapFree 内部出现一些错误指示() 我怀疑是指堆损坏.

If the type new[]'ed has a non-trivial constructor or destructor the above trick can't be done - VC++7 has to invoke exactly the right number of destructors. So it prepends the array with a size_t storing the number of elements. Now the address returned by new[] points onto the first element, not onto the beginning of the block. So if delete is used it only calls the destructor for the first element and the calls "free memory" with the address different from the one returned by "allocate memory" and this leads to some error indicaton inside HeapFree() which I suspect refers to heap corruption.

然而,每个人都可以读到在 new[] 之后使用 delete 会导致内存泄漏的错误语句.我怀疑任何大小的堆损坏都比只为第一个元素调用析构函数并且可能未调用的析构函数没有释放堆分配的子对象这一事实重要得多.

Yet every here and there one can read false statements that using delete after new[] leads to a memory leak. I suspect that anything size of heap corruption is much more important than a fact that the destructor is called for the first element only and possibly the destructors not called didn't free heap-allocated sub-objects.

new[] 之后使用 delete 怎么可能只导致某些 C++ 实现的内存泄漏?

How could using delete after new[] possibly lead only to a memory leak on some C++ implementation?

推荐答案

假设我是一个 C++ 编译器,我像这样实现我的内存管理:我在每个保留内存块前面加上内存大小,以字节为单位.像这样;

Suppose I'm a C++ compiler, and I implement my memory management like this: I prepend every block of reserved memory with the size of the memory, in bytes. Something like this;

| size | data ... |
         ^
         pointer returned by new and new[]

注意,在内存分配方面,newnew[] 没有区别:都只是分配了一定大小的内存块.

Note that, in terms of memory allocation, there is no difference between new and new[]: both just allocate a block of memory of a certain size.

现在 delete[] 如何知道数组的大小,以便调用正确数量的析构函数?只需将内存块的size除以sizeof(T),其中T是数组元素的类型.

Now how will delete[] know the size of the array, in order to call the right number of destructors? Simply divide the size of the memory block by sizeof(T), where T is the type of elements of the array.

现在假设我将 delete 实现为对析构函数的简单调用,然后释放 size 字节,那么后续元素的析构函数将永远不会被调用.这会导致后续元素分配的资源泄漏.然而,因为我做释放 size 字节(不是 sizeof(T) 字节),所以不会发生堆损坏.

Now suppose I implement delete as simply one call to the destructor, followed by the freeing of the size bytes, then the destructors of the subsequent elements will never be called. This results in leaking resources allocated by the subsequent elements. Yet, because I do free size bytes (not sizeof(T) bytes), no heap corruption occurs.

相关文章