C ++中的deletedelete[]运算符有什么区别?

评论

您可能会发现此问题与stackoverflow.com/questions/1913343/…有关。

delete和delete []的问题是为什么我喜欢智能指针并尽可能使用vector <>而不是数组的原因之一。

stackoverflow.com/questions/1553382/…

@DavidThornley如果您使用的是智能指针,则仍然需要了解其区别,即您仍然需要知道不编写例如std :: unique_ptr (new int [3]),因为它将在未定义行为的数组上调用常规删除。相反,您需要使用std :: unique_ptr

#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-分配模式的基本用法
我们需要相应地使用它们。但我想对mallocfree之间的区别添加特殊的理解

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 楼

分别使用运算符deletedelete []销毁使用newnew[]创建的对象,并返回分配给编译器内存管理器可用的已分配内存。必须使用new销毁使用delete创建的对象,并且使用new[]创建的数组应使用delete[]删除。

#5 楼

当我问这个问题时,我真正的问题是:“两者之间有区别吗?运行时是否不必保留有关数组大小的信息,所以它不能说出我们的意思是哪一个吗?”这个问题不会出现在“相关问题”中,因此只是为了帮助像我这样的人,这是答案:“为什么我们甚至需要delete []运算符?”

评论


感谢您回来并将其放入。

– Ziffusion
18-09-22在22:08

#6 楼

delete用于单个指针,而delete[]用于通过指针删除数组。
这可以帮助您更好地理解。