new后可以用free吗
虽然语言不会阻止您这样做,但您永远不应该在使用C++new运算符收到的块上使用Cfree函数。始终对从new运算符接收的块使用C++delete运算符,对从new[]运算符接收的块使用delete[]运算符。
new运算符为您正在分配的数据类型执行构造函数,而new[]运算符为您正在分配的数组的每个元素执行构造函数。同样,delete运算符为对象执行析构函数,delete[]运算符为数组中的每个对象执行析构函数。free函数对析构函数一无所知,因此充其量,将free与您从new或new[]运算符收到的块一起使用将默默地无法调用任何析构函数,这可能导致资源泄漏,打开应关闭的文件,设备处于错误状态等
但是即使你正在使用的对象没有析构函数,也绝对不能保证new/delete机制使用与malloc/calloc/realloc/free机制相同的堆。实现不需要为两者使用相同的堆,而且我知道不需要的实现。但即使它们使用相同的堆,也不能保证关于块大小的信息(或其他一些其他细节)存储在相同的位置或以相同的格式存储两种机制。因此,如果您在使用new运算符或new[]运算符分配的块上使用free函数,您将面临泄漏该块的风险(因为free不知道如何处理它),或破坏malloc/freeheap和/或new/deleteheap——这会导致下游的各种严重问题。
当然,在C++中,new、new[]、delete和delete[]运算符是可以重载的。这些运算符的重载版本可能会使用完全不同的、开发人员定义的机制进行分配和释放,这些机制与默认的malloc/free堆或默认的new/delete堆无关。潜在地,每种数据类型都可以有自己的new、new[]、delete和delete[]运算符,其中任何一个都可能与默认的malloc/free或new/delete机制不兼容。即使您今天将free与来自new/new[]的块一起使用,并且它今天“恰好可以工作”,将来对类定义的更改(重载new/new[]/delete/delete[]),编译器实现的变化,甚至是编译器选项的变化,都会立即破坏您的代码。充其量,代码将不可移植。
底线:始终在new提供的块上使用delete,始终在new[]提供的块上使用delete[],始终在malloc/calloc/realloc提供的块上使用free,不要混合使用它们。如果你把它们混在一起,你只是在自找麻烦。