在 Exceptional C++ 中,Herb Sutter 在 Item 35 中作为指导写道:
更喜欢使用免费商店(新建/删除)。避免使用堆(malloc/free)。
我为什么要?
如果实现选择new
使用 using来实现malloc
,则可能会产生开销,因此就性能而言,这看起来像是一个糟糕的建议。
在 Exceptional C++ 中,Herb Sutter 在 Item 35 中作为指导写道:
更喜欢使用免费商店(新建/删除)。避免使用堆(malloc/free)。
我为什么要?
如果实现选择new
使用 using来实现malloc
,则可能会产生开销,因此就性能而言,这看起来像是一个糟糕的建议。
C++ 中的new
anddelete
关键字通常是用malloc
and来实现的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
,或处理零大小的请求等),但我希望这有助于解释它们new
的malloc
不同之处。
那么为什么要使用new
overmalloc
呢?嗯,有几个原因:
它更安全。 您可能忘记检查空指针的返回类型,malloc
或者您可能请求错误的存储空间量,或者您可能忘记调用对象的构造函数,或者如果构造函数抛出异常,您可能忘记释放内存, ETC。
它更安全。 malloc
返回 a void*
,它只是一个指向内存块的指针。使用malloc
,您必须将指针转换为正确的类型,这会在以后引入错误的可能性。
它允许定制。 某些类型operator new
以不寻常的方式重载以请求内存,例如从池分配器或某些可能更快的内存块,或使用优化使用模式的自定义分配器。T
鉴于此,您可以通过简单地定义operator new
和来自动自定义为类型对象动态分配内存的所有时间operator delete
。如果使用malloc
,则必须在整个程序中追踪所有内存分配站点。
也就是说,有一些优势malloc
。如果您确定要分配的对象是普通对象(例如仅保存数据的基元或结构),则使用malloc
. malloc
也可以让你使用realloc
,free
但不能。std::vector
但老实说,在这种情况下你可能会更好std::array
,因为它们更安全,更容易调试,并且具有良好的编译器支持可能会被积极优化。
希望这可以帮助!