在Exceptional C ++中,Herb Sutter在第35项中写道:
首选使用免费商店(新/删除)。避免使用堆 (malloc的/自由)。
我为什么要这样?
如果某个实现选择使用new
来实现malloc
,则可能会产生开销,因此就性能而言,这看起来很糟糕。
答案 0 :(得分:11)
C ++中的new
和delete
关键字通常以malloc
和free
的形式实现,但它们的目的是做不同的事情。
在C ++中,如果你说
new T(/* args */)
C ++将执行以下操作:
T
类型的对象。std::bad_alloc
对象。T
的对象。T
类型的对象引发异常,则自动释放内存。如果您只使用malloc
,则必须手动执行所有这些步骤,这非常非常非常。它可能看起来像这样:
T* memory = nullptr;
while (true) {
memory = static_cast<T*>(malloc(sizeof(T)));
if (memory != nullptr) break;
std::get_new_handler()();
}
try {
new (memory) T(/* args */);
} catch (...) {
free(memory);
throw;
}
我在这里有一些其他的细微差别(比如调用operator new
代替malloc
,或处理零大小的请求等),但我希望这有助于解释{ {1}}和new
不同。
那么为什么要使用malloc
而不是new
?嗯,有几个原因:
它更安全。使用malloc
您可以忘记检查空指针的返回类型,或者您可以请求错误的存储空间量,或者您可以忘记在对象上调用构造函数,否则如果构造函数抛出异常等,你可能会忘记释放内存。
它更加类型安全。 malloc
返回malloc
,它只是指向内存块的指针。使用void*
,您必须将指针强制转换为正确的类型,这可能会在以后引入错误。
它允许自定义。某些类型重载malloc
以异常方式请求内存,例如来自池化分配器或可能更快的某些内存块,或者使用优化使用模式的自定义分配器。鉴于此,您可以通过定义operator new
和T
自动自定义为operator new
类型的对象动态分配内存的所有时间。如果您使用operator delete
,则必须在整个程序中追踪所有内存分配站点。
也就是说,malloc
有一些优点。如果您确定要分配的对象是简单的对象(例如只保存数据的基元或结构),则使用malloc
可能会稍快一些。 malloc
还允许您使用malloc
,realloc
不会。但老实说,在这样的情况下,你可能最好只使用free
或std::vector
,因为它们更安全,更容易调试,并且具有良好的编译器支持可能会被积极地优化。 / p>
希望这有帮助!