删除操作符如何工作?它比free()更好吗?此外,如果您执行ptr=new char[10]
,然后使用delete ptr
删除,指针如何知道要删除的位置数。
答案 0 :(得分:16)
只有delete
运算符,free
仅作为函数存在。在C ++下,我们鼓励您使用new
/ delete
而不是malloc()
/ free()
。
删除操作符中有一个内部“魔术”。使用new[]
创建数组时,数组的大小存储在内存块的元数据中。 delete[]
使用该信息。
所有这些当然都是编译器,操作系统,优化器和实现依赖。
答案 1 :(得分:5)
如果您执行非数组类型:
T t = new T;
// ...
delete t;
它会知道要删除多少,因为它知道T有多大。如果你做一个数组:
T t* = new T[10];
// ...
delete [] t;
它会在分配时放下一些额外的信息,告诉它要删除多少。注意,我们使用delete [] t
和额外的[]
来告诉它它是一个数组。如果你不这样做,它会认为它只是一个T
并且只释放那么多记忆。
如果您使用delete
,则始终使用new
;如果您使用free
,则始终使用malloc
。 new
首先分配内存,然后构造对象。类似地,delete
调用析构函数然后释放内存。 malloc\free
只处理内存分配和释放。
答案 2 :(得分:3)
在C ++中,使用new调用构造函数,但在使用malloc时则调用。类似地,使用delete时会调用析构函数,但在使用free时不会调用析构函数。
如果您使用MyClass * x = new MyClass [25]创建了一个新数组,那么您需要调用delete [] x,以便系统知道它正在删除(和破坏)一组对象而不是单个对象。
答案 3 :(得分:3)
实现计算出要销毁的元素数量(当使用delete []时)。例如:
答案 4 :(得分:3)
这不是一个好或坏的问题。两者都是具有相同目标的操作,分配和释放内存,但通常在C与C ++的不同上下文中使用。此外,两组操作之间存在一些重要差异:
new
/ delete
是C ++关键字,在C语言中不可用new
/ delete
是类型安全的,而malloc()
/ free()
则不是。这意味着malloc()
和free()
返回的指针是void
指针,需要转换为正确的类型。new
/ delete
使用new[]
和delete[]
语法使用编译器提供的元数据malloc()
/ {隐式支持数组分配和删除{1}}不支持此语法free()
/ new
应用于类类型delete
将分别调用T
,T
/ malloc()
的构造函数和析构函数不要调用free()
T
将返回malloc()
,NULL
将引发异常请注意,为防止内存损坏,应使用new
释放使用new
分配的内存。对于使用delete
分配的内存也是如此,应使用malloc()
释放内存。
答案 5 :(得分:3)
具体回答你的问题,删除操作符调用析构函数,其中free是不会;因此你不想将malloc / free与new / delete混合使用。
当编译器的库从堆中抓取内存时,它抓取的内容比你要求的多一点,其中包括空间保存,一些元数据,以及必要时填充。
假设您使用malloc 128字节,或者新建一个包含8个16字节大小的对象的数组。编译器实际上可能会抓取256个字节,在开始时包含一个小堆管理块,记录它给你128但是抓住了256,然后在它的标题之后的某个地方返回一个偏移到256块。您可以保证从该指针可以使用128个字节,但如果超出该字节,则可能会遇到麻烦。
引擎盖下的free和delete操作符将获取你所处理的指针,备份已知的偏移量,读取它的标题块,并知道将256个字节释放回堆中。
答案 6 :(得分:2)
如果使用运算符的new []形式分配内存,请添加@ Vlad的答案,如:
char *c = new char[10];
然后你必须使用相应的删除表格:
delete[] c;
您必须明确告诉编译器在重新分配期间使用元数据。
[编辑]
为什么你不能使用char c []
因为编译器需要知道在编译时需要为变量c留出的大小。但是,使用new []表单会告诉它将分配推迟到运行时。因此,编译错误。