delete
和delete[]
运算符有什么区别?#1 楼
delete
运算符为由new
创建的单个对象释放内存并调用析构函数。delete []
运算符为由new []
创建的对象数组释放内存并调用析构函数。在
delete
返回的指针上使用new []
或delete []
返回的指针上使用new
会导致未定义的行为。评论
我想知道是否在像int或char这样的原始类型的new []数组上使用delete也必然导致未定义的行为。使用基本类型时,似乎数组大小没有存储在任何地方。
– thomiel
2014年7月6日在11:16
如果该标准没有定义完成该操作后将发生的情况,则即使定义了编译器确定要执行的操作,它也被定义为“未定义的行为”。另一个编译器可能会做完全不同的事情。
– Rob K
2014年12月23日15:24在
当我有一个像“ char ** strArray”这样的C字符串数组时,我犯了这个错误。如果您有一个像我一样的数组,则需要遍历该数组并删除/释放每个元素,然后删除/释放strArray本身。在我拥有的阵列上使用“ delete []”不起作用,因为(如上述评论和回答所指出的),IT调用了DESTRUCTORS,实际上并没有释放每个插槽。
–凯蒂妮(Katianie)
16年5月26日在3:22
#2 楼
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
具有第二个类型为q4312079q的参数,它将接收要取消分配的元素数。 #3 楼
这在c ++中的分配/ DE-分配模式的基本用法我们需要相应地使用它们。但我想对
malloc
和free
之间的区别添加特殊的理解1)
new
用于取消分配为单个对象分配的内存2)
delete
是用于取消分配为对象数组分配的内存class ABC{}
ABC *ptr = new ABC[100]
当我们说
new[]
时,编译器可以获得有关需要分配多少个对象的信息(在此处是100),并将为每个创建的对象调用构造函数,但是相应地,如果在这种情况下我们仅使用
delete[]
,则编译器将不知道delete
指向了多少个对象,最终将调用的析构函数并仅删除1个对象的内存(不调用析构函数并释放剩余的99个对象)。因此会发生内存泄漏。,所以在这种情况下,我们需要使用
delete[]
。评论
这应该是正确的答案。其他答案都没有提到明显的区别:“但是相应地,如果在这种情况下我们仅使用delete ptr,则编译器将不知道ptr指向多少个对象,最终将调用析构函数并仅删除1个对象的内存”
– Don Larynx
15年6月14日在1:22
我们如何在C语言中实现同一目标?
–Dogus Ural
17年4月28日在19:10
@DogusUral为什么? C中没有析构函数,因此您只需要free()this and that。如果使用伪析构函数模式,则必须使用for循环为每个对象调用一次。
–Kotauskas
19-10-13在15:22
@DonLarynx的正确区别是将它们混合在一起会导致程序格式错误。一个实现可能知道要销毁多少个对象,也可能不知道。可以知道它被称为错误,并中止程序以告诉您问题出在哪里。
– Caleth
5月15日8:34
#4 楼
分别使用运算符delete
和delete []
销毁使用new
和new[]
创建的对象,并返回分配给编译器内存管理器可用的已分配内存。必须使用new
销毁使用delete
创建的对象,并且使用new[]
创建的数组应使用delete[]
删除。#5 楼
当我问这个问题时,我真正的问题是:“两者之间有区别吗?运行时是否不必保留有关数组大小的信息,所以它不能说出我们的意思是哪一个吗?”这个问题不会出现在“相关问题”中,因此只是为了帮助像我这样的人,这是答案:“为什么我们甚至需要delete []运算符?”评论
感谢您回来并将其放入。
– Ziffusion
18-09-22在22:08
#6 楼
delete
用于单个指针,而delete[]
用于通过指针删除数组。这可以帮助您更好地理解。
评论
您可能会发现此问题与stackoverflow.com/questions/1913343/…有关。delete和delete []的问题是为什么我喜欢智能指针并尽可能使用vector <>而不是数组的原因之一。
stackoverflow.com/questions/1553382/…
@DavidThornley如果您使用的是智能指针,则仍然需要了解其区别,即您仍然需要知道不编写例如std :: unique_ptr