2010-03-11 112 views
70

deletedelete[]运算符在C++中有什么区别?删除与删除[] C++运算符

+0

你可能会发现这个问题相关http://stackoverflow.com/questions/1913343/how-could-pairing-new-with-delete-possibly-lead-to-memory-leak-only – sharptooth 2010-03-11 14:45:29

+4

与删除和delete []是我喜欢智能指针的原因之一,并且只要我可以使用'vector <>'而不是数组。 – 2010-03-11 15:33:28

+0

http://stackoverflow.com/questions/1553382/pod-freeing-memory-is-delete-equal-to-delete – sbi 2011-01-12 16:05:08

回答

88

delete运算符取消分配内存并调用用new创建的单个对象的析构函数。

delete []运算符释放内存并调用用new []创建的对象数组的析构函数。

在由new返回的指针上返回的指针new []delete []上使用delete会导致未定义的行为。

+1

我不知道如果使用删除一个新的[]原始类型的数组,如int或char(无构造函数/析构函数)也必然导致未定义的行为。看起来,使用基元类型时,数组的大小并不存储在任何地方。 – thomiel 2014-07-06 11:16:02

+12

如果标准没有定义完成后会发生什么,即使您的编译器确定地执行了您希望的操作,它也是定义为“未定义的行为”。另一个编译器可能会完全不同。 – 2014-12-23 15:24:24

+0

当我有一个像“char ** strArray”这样的C字符串数组时,我犯了这个错误。如果你有像我这样的数组,你需要遍历数组并删除/释放每个元素,然后删除/释放strArray本身。使用“删除[]”阵列我没有工作,因为(如上面的评论和回答指出),它呼叫DESTRUCTORS,它实际上并没有释放每个插槽。 – Katianie 2016-05-26 03:22:58

4

运营商deletedelete []分别用于销毁用newnew[]创建的对象,返回到编译器内存管理器可用的已分配内存。

使用new创建的对象必须使用delete销毁,并且使用new[]创建的数组应该使用delete[]删除。

75

delete[]运算符用于删除数组。 delete运算符用于删除非数组对象。它分别调用operator delete[]operator delete函数来删除数组或非数组对象在(最终)调用数组元素或非数组对象的析构函数之后占用的内存。

以下显示了关系:

typedef int array_type[1]; 

// create and destroy a int[1] 
array_type *a = new array_type; 
delete [] a; 

// create and destroy an int 
int *b = new int; 
delete b; 

// create and destroy an int[1] 
int *c = new int[1]; 
delete[] c; 

// create and destroy an int[1][2] 
int (*d)[2] = new int[1][2]; 
delete [] d; 

对于new创建的阵列(这样,无论是应用于阵列型构建体中的new type[]new),标准在该数组元素查找一个operator new[]类型类或全局作用域中,并传递请求的内存量。如果需要,它可能会请求超过N * sizeof(ElementType)(例如,要存储元素的数量,所以在以后删除时知道要完成多少析构函数调用)。如果这个类声明了一个operator new[],那么额外的内存容量可以接受另一个size_t,那么第二个参数将会接收到分配的元素数 - 它可能会将它用于任何想要的目的(调试等等)。

对于创建非数组对象的new,它将在元素的类或全局范围中查找operator new。它传递请求的内存量(总是sizeof(T))。

对于delete[],它查看数组的元素类类型并调用它们的析构函数。所使用的operator delete[]函数是元素类型的类中的函数,或者是全局范围内没有的函数。

对于delete,如果传递的指针是实际对象类型的基类,则基类必须具有虚拟析构函数(否则行为未定义)。如果它不是基类,则调用该类的析构函数,并使用该类中的operator delete或全局operator delete。如果传递了基类,则调用实际的对象类型的析构函数,并使用该类中找到的operator delete,如果没有,则调用全局的operator delete。如果该类中的operator delete具有size_t类型的第二个参数,它将接收要释放的元素数量。

8

这基本使用分配/在C DE-分配格局++ 的malloc /免费,新/删除,新的[] /删除[]

我们需要相应地使用它们。但我想添加此特定的认识为删除之间的差和删除[]

1)删除用于分配用于单个对象

2)删除解除分配存储器[]用于解除分配存储器分配用于阵列对象的

类ABC {}

ABC * PTR =新ABC [100]

,当我们说新的[100] ..编译器可以了解有多少对象需要分配的信息(这里是100),并调用构造每个对象的创建

,但相应地,如果我们简单地用删除PTR这种情况下,编译器将不知道PTR指向并最终将调用析构函数和删除记忆多少个对象只有1个对象(留下调用析构函数并释放剩余的99个对象)。因此会出现内存泄漏

所以我们需要在这种情况下使用delete [] ptr

+2

这应该是正确的答案。其他答案都没有提到明显的区别:“但是相应地,如果我们在这种情况下简单地使用delete ptr,编译器将不知道ptr指向多少个对象,并且最终只会调用析构函数并删除只有一个对象的内存” – 2015-06-14 01:22:15

+0

我们如何在C中实现同样的事情? – 2017-04-28 19:10:42

-1

delete用于单个指针,delete[]用于通过指针删除数组。 This可能会帮助你更好地理解。

0

当我问到这个问题时,我真正的问题是,“这两者之间有什么区别吗?运行时不必保留关于数组大小的信息,所以也不能告诉我们哪一个意思?”这个问题没有出现在“相关问题”中,所以只是为了帮助像我这样的人,这里是答案:"why do we even need the delete[] operator?"

0

好吧..也许我认为这只是为了明确。 运算符删除和运算符delete []区别但删除运算符也可以释放数组。

test* a = new test[100]; 
delete a; 

而且已经检查过这个代码没有memeory泄漏。