为什么在delete (delete[])中使用[]来释放动态分配的数组?

时间:2022-03-01 01:03:07

I know that when delete [] will cause destruction for all array elements and then releases the memory.

我知道,当delete[]将对所有数组元素造成破坏,然后释放内存。

I initially thought that compiler wants it just to call destructor for all elements in the array, but I have also a counter - argument for that which is:

我最初认为编译器想要它只是为数组中的所有元素调用析构函数,但我也有一个反参数,它是:

Heap memory allocator must know the size of bytes allocated and using sizeof(Type) its possible to find no of elements and to call appropriate no of destructors for an array to prevent resource leaks.

堆内存分配器必须知道分配的字节的大小,并且使用sizeof(类型)可以找到没有元素,并为数组调用适当的no析构函数以防止资源泄漏。

So my assumption is correct or not and please clear my doubt on it.

所以我的假设是正确的,请澄清我的怀疑。

So I am not getting the usage of [] in delete [] ?

所以我没有在删除[]中使用[]?

5 个解决方案

#1


35  

Scott Meyers says in his Effective C++ book: Item 5: Use the same form in corresponding uses of new and delete.

Scott Meyers在他的有效的c++书籍中说:项目5:在新的和删除的相应使用中使用相同的表单。

The big question for delete is this: how many objects reside in the memory being deleted? The answer to that determines how many destructors must be called.

删除的最大问题是:有多少对象驻留在被删除的内存中?答案决定了必须调用多少析构函数。

Does the pointer being deleted point to a single object or to an array of objects? The only way for delete to know is for you to tell it. If you don't use brackets in your use of delete, delete assumes a single object is pointed to.

被删除的指针是指向单个对象还是指向对象数组?删除的唯一方法是让你告诉它。如果您在使用delete时不使用方括号,那么删除假设一个对象被指向。

Also, the memory allocator might allocate more space that required to store your objects and in this case dividing the size of the memory block returned by the size of each object won't work.

此外,内存分配器可能会分配更多存储对象所需的空间,在这种情况下,将返回的内存块大小除以每个对象的大小是行不通的。

Depending on the platform, the _msize (windows), malloc_usable_size (linux) or malloc_size (osx) functions will tell you the real length of the block that was allocated. This information can be exploited when designing growing containers.

根据平台的不同,_msize (windows)、malloc_usable_size (linux)或malloc_size (osx)函数将告诉您分配的块的实际长度。这些信息可以在设计种植容器时加以利用。

Another reason why it won't work is that Foo* foo = new Foo[10] calls operator new[] to allocate the memory. Then delete [] foo; calls operator delete[] to deallocate the memory. As those operators can be overloaded, you have to adhere to the convention otherwise delete foo; calls operator delete which may have an incompatible implementation with operator delete []. It's a matter of semantics, not just keeping track of the number of allocated object to later issue the right number of destructor calls.

它不能工作的另一个原因是Foo* Foo = new Foo[10]调用操作符new[]来分配内存。然后删除[]foo;调用操作符delete[]来释放内存。由于这些操作符可以重载,所以您必须遵守约定,否则删除foo;调用操作符delete,它可能与操作符delete[]实现不兼容。这是一个语义问题,而不仅仅是跟踪分配的对象的数量,以便稍后发出正确的析构函数调用数量。

See also:

参见:

[16.14] After p = new Fred[n], how does the compiler know there are n objects to be destructed during delete[] p?

[16.14]在p = new Fred[n]之后,编译器如何知道在delete[] p过程中有n个对象要被销毁?

Short answer: Magic.

简短的回答:魔法。

Long answer: The run-time system stores the number of objects, n, somewhere where it can be retrieved if you only know the pointer, p. There are two popular techniques that do this. Both these techniques are in use by commercial-grade compilers, both have tradeoffs, and neither is perfect. These techniques are:

长话短说:运行时系统存储对象的数量n,如果您只知道指针p,那么它就可以被检索到。这两种技术都在商业级编译器中使用,两者都有权衡,而且都不完美。这些技术包括:


EDIT: after having read @AndreyT comments, I dug into my copy of Stroustrup's "The Design and Evolution of C++" and excerpted the following:

编辑:在阅读了@AndreyT的评论后,我深入研究了Stroustrup的“c++的设计和演变”,并摘录如下:

How do we ensure that an array is correctly deleted? In particular, how do we ensure that the destructor is called for all elements of an array?

如何确保数组被正确地删除?特别是,如何确保对数组的所有元素调用析构函数?

...

Plain delete isn't required to handle both individual objects an arrays. This avoids complicating the common case of allocating and deallocating individual objects. It also avoids encumbering individual objects with information necessary for array deallocation.

不需要纯删除来处理数组中的两个单独对象。这避免了分配和释放单个对象的常见情况复杂化。它还避免了将数组释放所需的信息累加到单个对象中。

An intermediate version of delete[] required the programmer to specify the number of elements of the array.

delete[]的中间版本要求程序员指定数组元素的数量。

...

That proved too error prone, so the burden of keeping track of the number of elements was placed on the implementation instead.

事实证明,这样做太容易出错,因此将跟踪元素数量的重担放在实现上。

As @Marcus mentioned, the rational may have been "you don't pay for what you don't use".

正如@Marcus提到的,rational可能是“你不为你不使用的东西付钱”。


EDIT2:

EDIT2:

In "The C++ Programming Language, 3rd edition", §10.4.7, Bjarne Stroustrup writes:

在《c++编程语言,第3版”,§10.4.7,dennis ritchie写道:

Exactly how arrays and individual objects are allocated is implementation-dependent. Therefore, different implementations will react differently to incorrect uses of the delete and delete[] operators. In simple and uninteresting cases like the previous one, a compiler can detect the problem, but generally something nasty will happen at run time.

数组和单个对象的分配方式与实现有关。因此,不同的实现对于不正确地使用delete和delete[]操作符会有不同的反应。在像前一种简单而无趣的情况下,编译器可以检测问题,但是通常在运行时会发生一些令人讨厌的事情。

The special destruction operator for arrays, delete[], isn’t logically necessary. However, suppose the implementation of the free store had been required to hold sufficient information for every object to tell if it was an individual or an array. The user could have been relieved of a burden, but that obligation would have imposed significant time and space overheads on some C++ implementations.

数组的特殊销毁操作符delete[]在逻辑上没有必要。然而,假设*存储的实现被要求持有足够的信息,以便每个对象都能判断它是单个对象还是数组。用户本可以减轻负担,但这种义务会给一些c++实现带来大量的时间和空间开销。

#2


9  

The main reason why it was decided to keep separate delete and delete[] is that these two entities are not as similar as it might seem at the first sight. For a naive observer they might seem to be almost the same: just destruct and deallocate, with the only difference in the potential number of objects to process. In reality, the difference is much more significant.

之所以决定保留单独的delete和delete[]的主要原因是这两个实体并不像乍看起来那样相似。对于一个天真的观察者来说,它们看起来几乎是一样的:仅仅是破坏和释放,在潜在的对象数量上有唯一的区别。事实上,两者之间的差异要大得多。

The most important difference between the two is that delete might perform polymorphic deletion of objects, i.e. the static type of the object in question might be different from its dynamic type. delete[] on the other hand must deal with strictly non-polymorphic deletion of arrays. So, internally these two entities implement logic that is significantly different and non-intersecting between the two. Because of the possibility of polymorphic deletion, the functionality of delete is not even remotely the same as the functionality of delete[] on an array of 1 element, as a naive observer might incorrectly assume initially.

两者之间最重要的区别是,delete可能执行对象的多态删除,即所涉及对象的静态类型可能与其动态类型不同。另一方面,delete[]必须严格处理数组的非多态性删除。因此,在内部这两个实体实现的逻辑与两者之间存在显著的不同和非交叉。由于多态删除的可能性,delete的功能甚至与delete[]在一个元素的数组上的功能根本不相同,因为一个天真的观察者最初可能会错误地假设。

Contrary to the strange claims made in some other answers, it is, of course, perfectly possible to replace delete and delete[] with just a single construct that would branch at the very early stage, i.e. it would determine the type of the memory block (array or not) using the household information that would be stored by new/new[], and then jump to the appropriate functionality, equivalent to either delete or delete[]. However, this would be a rather poor design decision, since, once again, the functionality of the two is too different. Forcing both into a single construct would be akin to creating a Swiss Army Knife of a deallocation function. Also, in order to be able to tell an array from a non-array we'd have to introduce an additional piece of household information even into a single-object memory allocations done with plain new. This might easily result in notable memory overhead in single object allocations.

奇怪的主张相反在其他一些答案,,当然,完全有可能取代删除和删除[]只有一个构造分支在非常早期的阶段,即它将确定内存块的类型(数组)使用的家庭信息将存储新/新[],然后跳转到相应的功能,相当于删除或删除[]。然而,这将是一个相当糟糕的设计决策,因为这两者的功能又是如此的不同。将两者都强制到一个单一结构中,就像创建一个释放函数的瑞士军刀。此外,为了能够区分数组和非数组,我们必须引入一个额外的家庭信息,甚至是使用plain new完成的单对象内存分配。这很容易在单个对象分配中产生显著的内存开销。

But, once again, the main reason here is the functional difference between delete and delete[]. These language entities possess only apparent skin-deep similarity that exists only at the level of naive specification ("destruct and free memory"), but once one gets to understand in detail what these entities really have to do one realizes that they are too different to be merged into one.

但是,这里的主要原因是delete和delete[]之间的功能差异。这些语言实体仅具有明显的表面相似性,它们只存在于朴素规范的层次(“破坏和*内存”),但是一旦人们详细了解了这些实体真正需要做什么,就会意识到它们是太不同而不能合并成一个。

P.S. This is BTW one of the problems with the suggestion about sizeof(type) you made in the question. Because of the potentially polymorphic nature of delete, you don't know the type in delete, which is why you can't obtain any sizeof(type). There are more problems with this idea, but that one is already enough to explain why it won't fly.

顺便说一句,这是你在问题中提出的关于尺寸(类型)的建议的一个问题。由于delete具有潜在的多态性,所以您不知道delete中的类型,这就是为什么您不能获得任何sizeof(类型)。这个想法有更多的问题,但这个问题已经足以解释为什么它不会飞了。

#3


3  

The heap itself knows the size of allocated block - you only need the address. Look like free() works - you only pass the address and it frees memory.

堆本身知道分配的块的大小—您只需要地址。看起来free()是有效的——您只传递地址,它释放内存。

The difference between delete (delete[]) and free() is that the former two first call the destructors, then free memory (possibly using free()). The problem is that delete[] also has only one argument - the address and having only that address it need to know the number of objects to run destructors on. So new[] uses som implementation-defined way of writing somewhere the number of elements - usually it prepends the array with the number of elements. Now delete[] will rely on that implementation-specific data to run destructors and then free memory (again, only using the block address).

delete (delete[])和free()之间的区别是,前者首先调用析构函数,然后调用空闲内存(可能使用free()))。问题是delete[]也只有一个参数——地址,并且只有这个地址,它需要知道要运行析构函数的对象数量。因此,new[]使用som实现定义的方式在某个地方写入元素的数量——通常它在数组中加上元素的数量。现在delete[]将依赖于特定于实现的数据来运行析构函数,然后释放内存(同样,只使用块地址)。

#4


1  

delete[] just calls a different implementation (function);

delete[]只调用一个不同的实现(函数);

There's no reason an allocator couldn't track it (in fact, it would be easy enough to write your own).

分配器没有理由不能跟踪它(事实上,编写自己的分配器很容易)。

I don't know the reason they did not manage it, or the history of the implementation, if I were to guess: Many of these 'well, why wasn't this slightly simpler?' questions (in C++) came down to one or more of:

我不知道他们没有管理它的原因,也不知道实现的历史,如果我要猜的话:许多这样的“为什么不简单一点呢?”“问题(用c++)归结为一个或多个:

  1. compatibility with C
  2. 兼容C
  3. performance
  4. 性能

In this case, performance. Using delete vs delete[] is easy enough, I believe it could all be abstracted from the programmer and be reasonably fast (for general use). delete[] only requires only a few additional function calls and operations (omitting destructor calls), but that is per call to delete, and unnecessary because the programmer generally knows the type he/she is dealing with (if not, there's likely a bigger problem at hand). So it just avoids calling through the allocator. Additionally, these single allocations may not need to be tracked by the allocator in as much detail; Treating every allocation as an array would require additional entries for count for trivial allocations, so it is multiple levels of simple allocator implementation simplifications which are actually important for many people, considering it is a very low level domain.

在这种情况下,性能。使用delete vs delete[]是很容易的,我相信它可以从程序员中抽象出来,并且可以相当快地(用于一般用途)。delete[]只需要一些额外的函数调用和操作(省略析构函数调用),但这是每次调用都要删除的,而且没有必要,因为程序员通常知道他/她正在处理的类型(如果没有的话,可能会有一个更大的问题)。它只是避免通过分配器调用。此外,这些单一分配可能不需要在分配程序中进行详细的跟踪;将每个分配都当作一个数组来处理,需要额外的条目来计算微不足道的分配,因此对于许多人来说,简单的分配器实现简化是非常重要的,因为它是一个非常低的级别域。

#5


-1  

This is more complicated.

这是更复杂的。

The keyword and the convention to use it to delete an array was invented for the convenience of implementations, and some implementations do use it (I don't know which though. MS VC++ does not).

关键字和使用它来删除数组的约定是为了实现的方便而发明的,一些实现确实使用它(我不知道是哪一个)。vc++女士不)。

The convenience is this:

方便是这样的:

In all other cases, you know the exact size to be freed by other means. When you delete a single object, you can have the size from compile-time sizeof(). When you delete a polymorphic object by base pointer and you have a virtual destructor, you can have the size as a separate entry in vtbl. If you delete an array, how would you know the size of memory to be freed, unless you track it separately?

在所有其他情况下,您都知道通过其他方式释放的确切大小。当您删除单个对象时,您可以从编译时sizeof()中获得大小。当您使用基指针删除一个多态对象并拥有一个虚拟析构函数时,您可以在vtbl中将其大小作为一个单独的条目。如果您删除了一个数组,那么如何知道要释放的内存大小,除非您单独跟踪它?

The special syntax would allow tracking such size only for an array - for instance, by putting it before the address that is returned to the user. This takes up additional resources and is not needed for non-arrays.

特殊语法只允许跟踪数组的大小——例如,将它放在返回给用户的地址之前。这将占用额外的资源,非数组不需要这些资源。

#1


35  

Scott Meyers says in his Effective C++ book: Item 5: Use the same form in corresponding uses of new and delete.

Scott Meyers在他的有效的c++书籍中说:项目5:在新的和删除的相应使用中使用相同的表单。

The big question for delete is this: how many objects reside in the memory being deleted? The answer to that determines how many destructors must be called.

删除的最大问题是:有多少对象驻留在被删除的内存中?答案决定了必须调用多少析构函数。

Does the pointer being deleted point to a single object or to an array of objects? The only way for delete to know is for you to tell it. If you don't use brackets in your use of delete, delete assumes a single object is pointed to.

被删除的指针是指向单个对象还是指向对象数组?删除的唯一方法是让你告诉它。如果您在使用delete时不使用方括号,那么删除假设一个对象被指向。

Also, the memory allocator might allocate more space that required to store your objects and in this case dividing the size of the memory block returned by the size of each object won't work.

此外,内存分配器可能会分配更多存储对象所需的空间,在这种情况下,将返回的内存块大小除以每个对象的大小是行不通的。

Depending on the platform, the _msize (windows), malloc_usable_size (linux) or malloc_size (osx) functions will tell you the real length of the block that was allocated. This information can be exploited when designing growing containers.

根据平台的不同,_msize (windows)、malloc_usable_size (linux)或malloc_size (osx)函数将告诉您分配的块的实际长度。这些信息可以在设计种植容器时加以利用。

Another reason why it won't work is that Foo* foo = new Foo[10] calls operator new[] to allocate the memory. Then delete [] foo; calls operator delete[] to deallocate the memory. As those operators can be overloaded, you have to adhere to the convention otherwise delete foo; calls operator delete which may have an incompatible implementation with operator delete []. It's a matter of semantics, not just keeping track of the number of allocated object to later issue the right number of destructor calls.

它不能工作的另一个原因是Foo* Foo = new Foo[10]调用操作符new[]来分配内存。然后删除[]foo;调用操作符delete[]来释放内存。由于这些操作符可以重载,所以您必须遵守约定,否则删除foo;调用操作符delete,它可能与操作符delete[]实现不兼容。这是一个语义问题,而不仅仅是跟踪分配的对象的数量,以便稍后发出正确的析构函数调用数量。

See also:

参见:

[16.14] After p = new Fred[n], how does the compiler know there are n objects to be destructed during delete[] p?

[16.14]在p = new Fred[n]之后,编译器如何知道在delete[] p过程中有n个对象要被销毁?

Short answer: Magic.

简短的回答:魔法。

Long answer: The run-time system stores the number of objects, n, somewhere where it can be retrieved if you only know the pointer, p. There are two popular techniques that do this. Both these techniques are in use by commercial-grade compilers, both have tradeoffs, and neither is perfect. These techniques are:

长话短说:运行时系统存储对象的数量n,如果您只知道指针p,那么它就可以被检索到。这两种技术都在商业级编译器中使用,两者都有权衡,而且都不完美。这些技术包括:


EDIT: after having read @AndreyT comments, I dug into my copy of Stroustrup's "The Design and Evolution of C++" and excerpted the following:

编辑:在阅读了@AndreyT的评论后,我深入研究了Stroustrup的“c++的设计和演变”,并摘录如下:

How do we ensure that an array is correctly deleted? In particular, how do we ensure that the destructor is called for all elements of an array?

如何确保数组被正确地删除?特别是,如何确保对数组的所有元素调用析构函数?

...

Plain delete isn't required to handle both individual objects an arrays. This avoids complicating the common case of allocating and deallocating individual objects. It also avoids encumbering individual objects with information necessary for array deallocation.

不需要纯删除来处理数组中的两个单独对象。这避免了分配和释放单个对象的常见情况复杂化。它还避免了将数组释放所需的信息累加到单个对象中。

An intermediate version of delete[] required the programmer to specify the number of elements of the array.

delete[]的中间版本要求程序员指定数组元素的数量。

...

That proved too error prone, so the burden of keeping track of the number of elements was placed on the implementation instead.

事实证明,这样做太容易出错,因此将跟踪元素数量的重担放在实现上。

As @Marcus mentioned, the rational may have been "you don't pay for what you don't use".

正如@Marcus提到的,rational可能是“你不为你不使用的东西付钱”。


EDIT2:

EDIT2:

In "The C++ Programming Language, 3rd edition", §10.4.7, Bjarne Stroustrup writes:

在《c++编程语言,第3版”,§10.4.7,dennis ritchie写道:

Exactly how arrays and individual objects are allocated is implementation-dependent. Therefore, different implementations will react differently to incorrect uses of the delete and delete[] operators. In simple and uninteresting cases like the previous one, a compiler can detect the problem, but generally something nasty will happen at run time.

数组和单个对象的分配方式与实现有关。因此,不同的实现对于不正确地使用delete和delete[]操作符会有不同的反应。在像前一种简单而无趣的情况下,编译器可以检测问题,但是通常在运行时会发生一些令人讨厌的事情。

The special destruction operator for arrays, delete[], isn’t logically necessary. However, suppose the implementation of the free store had been required to hold sufficient information for every object to tell if it was an individual or an array. The user could have been relieved of a burden, but that obligation would have imposed significant time and space overheads on some C++ implementations.

数组的特殊销毁操作符delete[]在逻辑上没有必要。然而,假设*存储的实现被要求持有足够的信息,以便每个对象都能判断它是单个对象还是数组。用户本可以减轻负担,但这种义务会给一些c++实现带来大量的时间和空间开销。

#2


9  

The main reason why it was decided to keep separate delete and delete[] is that these two entities are not as similar as it might seem at the first sight. For a naive observer they might seem to be almost the same: just destruct and deallocate, with the only difference in the potential number of objects to process. In reality, the difference is much more significant.

之所以决定保留单独的delete和delete[]的主要原因是这两个实体并不像乍看起来那样相似。对于一个天真的观察者来说,它们看起来几乎是一样的:仅仅是破坏和释放,在潜在的对象数量上有唯一的区别。事实上,两者之间的差异要大得多。

The most important difference between the two is that delete might perform polymorphic deletion of objects, i.e. the static type of the object in question might be different from its dynamic type. delete[] on the other hand must deal with strictly non-polymorphic deletion of arrays. So, internally these two entities implement logic that is significantly different and non-intersecting between the two. Because of the possibility of polymorphic deletion, the functionality of delete is not even remotely the same as the functionality of delete[] on an array of 1 element, as a naive observer might incorrectly assume initially.

两者之间最重要的区别是,delete可能执行对象的多态删除,即所涉及对象的静态类型可能与其动态类型不同。另一方面,delete[]必须严格处理数组的非多态性删除。因此,在内部这两个实体实现的逻辑与两者之间存在显著的不同和非交叉。由于多态删除的可能性,delete的功能甚至与delete[]在一个元素的数组上的功能根本不相同,因为一个天真的观察者最初可能会错误地假设。

Contrary to the strange claims made in some other answers, it is, of course, perfectly possible to replace delete and delete[] with just a single construct that would branch at the very early stage, i.e. it would determine the type of the memory block (array or not) using the household information that would be stored by new/new[], and then jump to the appropriate functionality, equivalent to either delete or delete[]. However, this would be a rather poor design decision, since, once again, the functionality of the two is too different. Forcing both into a single construct would be akin to creating a Swiss Army Knife of a deallocation function. Also, in order to be able to tell an array from a non-array we'd have to introduce an additional piece of household information even into a single-object memory allocations done with plain new. This might easily result in notable memory overhead in single object allocations.

奇怪的主张相反在其他一些答案,,当然,完全有可能取代删除和删除[]只有一个构造分支在非常早期的阶段,即它将确定内存块的类型(数组)使用的家庭信息将存储新/新[],然后跳转到相应的功能,相当于删除或删除[]。然而,这将是一个相当糟糕的设计决策,因为这两者的功能又是如此的不同。将两者都强制到一个单一结构中,就像创建一个释放函数的瑞士军刀。此外,为了能够区分数组和非数组,我们必须引入一个额外的家庭信息,甚至是使用plain new完成的单对象内存分配。这很容易在单个对象分配中产生显著的内存开销。

But, once again, the main reason here is the functional difference between delete and delete[]. These language entities possess only apparent skin-deep similarity that exists only at the level of naive specification ("destruct and free memory"), but once one gets to understand in detail what these entities really have to do one realizes that they are too different to be merged into one.

但是,这里的主要原因是delete和delete[]之间的功能差异。这些语言实体仅具有明显的表面相似性,它们只存在于朴素规范的层次(“破坏和*内存”),但是一旦人们详细了解了这些实体真正需要做什么,就会意识到它们是太不同而不能合并成一个。

P.S. This is BTW one of the problems with the suggestion about sizeof(type) you made in the question. Because of the potentially polymorphic nature of delete, you don't know the type in delete, which is why you can't obtain any sizeof(type). There are more problems with this idea, but that one is already enough to explain why it won't fly.

顺便说一句,这是你在问题中提出的关于尺寸(类型)的建议的一个问题。由于delete具有潜在的多态性,所以您不知道delete中的类型,这就是为什么您不能获得任何sizeof(类型)。这个想法有更多的问题,但这个问题已经足以解释为什么它不会飞了。

#3


3  

The heap itself knows the size of allocated block - you only need the address. Look like free() works - you only pass the address and it frees memory.

堆本身知道分配的块的大小—您只需要地址。看起来free()是有效的——您只传递地址,它释放内存。

The difference between delete (delete[]) and free() is that the former two first call the destructors, then free memory (possibly using free()). The problem is that delete[] also has only one argument - the address and having only that address it need to know the number of objects to run destructors on. So new[] uses som implementation-defined way of writing somewhere the number of elements - usually it prepends the array with the number of elements. Now delete[] will rely on that implementation-specific data to run destructors and then free memory (again, only using the block address).

delete (delete[])和free()之间的区别是,前者首先调用析构函数,然后调用空闲内存(可能使用free()))。问题是delete[]也只有一个参数——地址,并且只有这个地址,它需要知道要运行析构函数的对象数量。因此,new[]使用som实现定义的方式在某个地方写入元素的数量——通常它在数组中加上元素的数量。现在delete[]将依赖于特定于实现的数据来运行析构函数,然后释放内存(同样,只使用块地址)。

#4


1  

delete[] just calls a different implementation (function);

delete[]只调用一个不同的实现(函数);

There's no reason an allocator couldn't track it (in fact, it would be easy enough to write your own).

分配器没有理由不能跟踪它(事实上,编写自己的分配器很容易)。

I don't know the reason they did not manage it, or the history of the implementation, if I were to guess: Many of these 'well, why wasn't this slightly simpler?' questions (in C++) came down to one or more of:

我不知道他们没有管理它的原因,也不知道实现的历史,如果我要猜的话:许多这样的“为什么不简单一点呢?”“问题(用c++)归结为一个或多个:

  1. compatibility with C
  2. 兼容C
  3. performance
  4. 性能

In this case, performance. Using delete vs delete[] is easy enough, I believe it could all be abstracted from the programmer and be reasonably fast (for general use). delete[] only requires only a few additional function calls and operations (omitting destructor calls), but that is per call to delete, and unnecessary because the programmer generally knows the type he/she is dealing with (if not, there's likely a bigger problem at hand). So it just avoids calling through the allocator. Additionally, these single allocations may not need to be tracked by the allocator in as much detail; Treating every allocation as an array would require additional entries for count for trivial allocations, so it is multiple levels of simple allocator implementation simplifications which are actually important for many people, considering it is a very low level domain.

在这种情况下,性能。使用delete vs delete[]是很容易的,我相信它可以从程序员中抽象出来,并且可以相当快地(用于一般用途)。delete[]只需要一些额外的函数调用和操作(省略析构函数调用),但这是每次调用都要删除的,而且没有必要,因为程序员通常知道他/她正在处理的类型(如果没有的话,可能会有一个更大的问题)。它只是避免通过分配器调用。此外,这些单一分配可能不需要在分配程序中进行详细的跟踪;将每个分配都当作一个数组来处理,需要额外的条目来计算微不足道的分配,因此对于许多人来说,简单的分配器实现简化是非常重要的,因为它是一个非常低的级别域。

#5


-1  

This is more complicated.

这是更复杂的。

The keyword and the convention to use it to delete an array was invented for the convenience of implementations, and some implementations do use it (I don't know which though. MS VC++ does not).

关键字和使用它来删除数组的约定是为了实现的方便而发明的,一些实现确实使用它(我不知道是哪一个)。vc++女士不)。

The convenience is this:

方便是这样的:

In all other cases, you know the exact size to be freed by other means. When you delete a single object, you can have the size from compile-time sizeof(). When you delete a polymorphic object by base pointer and you have a virtual destructor, you can have the size as a separate entry in vtbl. If you delete an array, how would you know the size of memory to be freed, unless you track it separately?

在所有其他情况下,您都知道通过其他方式释放的确切大小。当您删除单个对象时,您可以从编译时sizeof()中获得大小。当您使用基指针删除一个多态对象并拥有一个虚拟析构函数时,您可以在vtbl中将其大小作为一个单独的条目。如果您删除了一个数组,那么如何知道要释放的内存大小,除非您单独跟踪它?

The special syntax would allow tracking such size only for an array - for instance, by putting it before the address that is returned to the user. This takes up additional resources and is not needed for non-arrays.

特殊语法只允许跟踪数组的大小——例如,将它放在返回给用户的地址之前。这将占用额外的资源,非数组不需要这些资源。