2014-02-15 101 views
0

在C中,free()用于释放内存,比如free(ptr)。据我所知,在库代码中的ptr之前分配额外的内存来存储块大小信息。在调用free()之后,整个块会被跟踪并释放。C++中的逻辑删除和删除[]

在C++中,有两种形式的new和delete。一个是数组。如果使用new[],则应使用delete[]。例如,

int ptr = new [10]; 
delete [] ptr; 

问题1:我可以在这里使用delete ptr吗?如果那是好的,如果delete ptr + 2

问题2:如果delete[]必须用于匹配new[],为什么我们需要两种形式的删除?只需要一个表格,例如delete就足够了。

感谢您的所有建议!

感谢Mgetz。问题2应该是:为什么C++标准在任何情况下都建议删除[]并删除如果只有一个正确格式?

+0

打开你的想法http://www.parashift.com/c++-faq/freestore-mgmt.html – lsalamon

+0

这是C++的尘土飞扬的角落之一。避免新的[]和删除[]像瘟疫。 – epx

回答

2

Q1:可以使用delete,但它是错误的。

这将通常“工作”,只要它能够正确释放分配的内存,但不会正确调用析构函数。对于微不足道的类型,你通常不会看到任何区别,但这并不意味着它不是错的。无论如何,这是未定义的行为,你应该避免,如果你可以(调用UB没收任何保证你的代码可以工作,它当然可以工作,但你永远无法100%确定)。
删除ptr+2也是未定义的行为,几乎肯定不会“工作”,甚至没有。通常情况下,这只会导致程序崩溃。

Q2:你需要两个,因为它们意味着不同的东西。一种意思是“删除这个指向单个对象的指针”,而另一种意思是“删除这个指向数组的指针”。
显然,编译器需要为这些不同的事情生成不同的代码。

+0

对于第1点,glibc在运行时告诉你,如果你有一个不匹配的allocate/deallocate对,并且取决于环境中的MALLOC_CHECK_的值,它可能会中止程序。这是一个明显的差异。 – SirGuy

+0

@GuyGreer:我的版本似乎并没有(通常它看起来“正常工作”,当然除非正确调用析构函数),但是如果你的构建警告甚至中止,那很好。我非常喜欢放弃或硬崩溃,而不是“无论如何”行为隐藏错误。努力放弃并尽早强制编写正确的代码。 – Damon

0

您需要这两种形式,因为与mallocfree,newdelete不同,不仅仅是分配和释放内存;他们也分别构建和破坏对象。

newdelete处理标量对象,而new[]delete[]处理对象数组。

当你调用new T[n],它会为Tn副本分配足够的内存,然后构建分配的内存中n实例。同样,调用delete[]将导致这些实例被破坏,然后再释放。

很明显,因为你不通过ndelete[]信息被藏匿的地方通过实施,但该标准不要求的实现,如果你打电话delete,而不是销毁所有n对象。该实现可能会破坏第一个对象,它可能会正确运行并销毁所有对象,或者可能导致demons to fly out of your nose

简单地说,它是未定义的行为,有没有说会发生什么,这是最好的当务之急你避免它。