我很清楚,在C ++中,delete[]
对new[]
是delete
,new
是delete[]
。这与C ++语法无关。我想知道原因 delete
被定义为与普通MyClass *object = new MyClass;
delete object;
不同的东西。这有什么实现原因?
考虑一下这段代码会发生什么:
delete
当遇到sizeof(MyClass)
时,内存管理器必须在其分配结构中查找对象指针值,无论它是什么,并将相应的MyClass *array = new MyClass[ num_objects ];
delete [] array;
内存块标记为空闲。
现在考虑一下这段代码会发生什么:
delete
当遇到num_objects
时,内存管理器必须在其分配结构中查找数组指针值,无论它是什么,从该结构中找到num_objects*sizeof(MyClass)
值,并标记相应的num_objects
内存块为免费。
除了在单个对象案例中假设为delete
并在数组中查找内部数据结构外,我没有看到差异。那么为什么delete[]
和MyClass *object = new MyClass;
不能拼写相同的拼写?
换句话说,
有什么问题MyClass *object = new MyClass[1];
实施为
delete
这样C ++语法就不必区分delete[]
和{{1}}?
答案 0 :(得分:22)
原则上,这些可以以相同的方式实施。然而,在某处存储元素的数量,迭代这些元素,并在每个元素上调用析构函数(在时间和空间方面都是如此)是成本。
C ++的核心理念之一是“不要为你不使用的东西买单”。由于与程序员可能不想支付的基于数组的分配和释放例程相关的额外成本,该语言明确地使两个操作分开。
希望这有帮助!
答案 1 :(得分:7)
首先,new/delete
的功能与new[]/delete[]
的功能不同。前者可用于执行多态分配和多态删除。后者根本不支持多态性。 C ++中的数组不是多态的,只有单个对象。可能有可能强制将这两个功能合并为一个,以便允许单个对象的多态删除并仍然保持数组的多态删除非法,但它看起来不会很漂亮。
其次,正如您可能知道的那样,new[]
的典型实现将在分配的数组中存储确切的对象数,稍后delete[]
将使用它来调用正确数量的析构函数。但是,当分配的类型具有普通的析构函数时,大多数现代实现实际上都会遇到 not 存储数组大小的麻烦。
为什么他们这样做?他们这样做是为了节省内存,即避免在可以避免的情况下存储大小。请注意,即使在相对内存丢失通常很小的情况下(一个size_t
字段与数组对象相比),它们也会遇到所有麻烦。
所以,显然这种节省内存的技术被认为是值得的。
在这种情况下很明显,在已知数组大小正好为1的情况下,它应该更值得,即从这个角度来看,实现new T
到new T[1]
将是非常浪费。