【为什么】new后可以用free吗

虽然语言不会阻止您这样做,但您永远不应该在使用 C++ new 运算符收到的块上使用 C free 函数。 始终对从 new 运算符接收的块使用 C++ delete 运算符,对从 new[] 运算符接收的块使用 delete[] 运算符。

new 运算符为您正在分配的数据类型执行构造函数,而 new[] 运算符为您正在分配的数组的每个元素执行构造函数。 同样,delete 运算符为对象执行析构函数,delete[] 运算符为数组中的每个对象执行析构函数。 free 函数对析构函数一无所知,因此充其量,将 free 与您从 new 或 new[] 运算符收到的块一起使用将默默地无法调用任何析构函数,这可能导致资源泄漏,打开应关闭的文件, 设备处于错误状态等

但是即使你正在使用的对象没有析构函数,也绝对不能保证 new/delete 机制使用与 malloc/calloc/realloc/free 机制相同的堆。 实现不需要为两者使用相同的堆,而且我知道不需要的实现。 但即使它们使用相同的堆,也不能保证关于块大小的信息(或其他一些其他细节)存储在相同的位置或以相同的格式存储两种机制。 因此,如果您在使用 new 运算符或 new[] 运算符分配的块上使用 free 函数,您将面临泄漏该块的风险(因为 free 不知道如何处理它),或破坏 malloc/free heap 和/或 new/delete heap——这会导致下游的各种严重问题。

当然,在 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,不要混合使用它们。 如果你把它们混在一起,你只是在自找麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值