【问题标题】:Why should I prefer using the free store over the heap?为什么我应该更喜欢使用免费存储而不是堆?
【发布时间】:2013-04-30 13:30:23
【问题描述】:

在 Exceptional C++ 中,Herb Sutter 在第 35 条中写道:

更喜欢使用免费商店(新建/删除)。避免使用堆 (malloc/free)。

我为什么要这样做?

如果实现选择通过使用malloc 来实现new,则可能会产生开销,因此就性能而言,这看起来像是一条糟糕的建议。

【问题讨论】:

  • malloc/free 根本不知道构造函数和析构函数是什么。这足以成为始终使用new/delete 的理由。
  • @syam:谢谢,但我认为任何 Exceptional C++ 的读者都已经知道mallocnew 之间的区别。我希望本书作者试图提出另一个观点。
  • @DarkWanderer 它没有:您的链接解释了newmalloc 之间的区别,我的问题是“为什么最好使用前者?”
  • @qdii:请再读一遍。 OP 特别强调了免费存储和堆之间的差异,而不是关于 malloc/free。接受的答案给出了很好的解释。

标签: c++ memory-management new-operator


【解决方案1】:

C++ 中的newdelete 关键字通常以mallocfree 的形式实现,但它们的设计目的不同。

在 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 和@ 987654335@不同。

那么为什么要使用new 而不是malloc?嗯,有几个原因:

  • 更安全。使用malloc,您可能会忘记检查空指针的返回类型,或者您可能请求错误的存储空间量,或者您可能忘记检查在对象上调用构造函数,或者如果构造函数抛出异常等,您可能会忘记释放内存。

  • 类型更安全。 malloc 返回一个 void*,它只是一个指向内存块的指针。使用malloc,您必须将指针转换为正确的类型,这会在以后引入错误的可能性。

  • 它允许自定义。某些类型重载 operator new 以不寻常的方式请求内存,例如从池分配器或可能更快的某些内存块,或使用优化使用模式的自定义分配器。鉴于此,您可以自动自定义为T 类型的对象动态分配内存的所有时间,只需定义operator newoperator delete。如果你使用malloc,你必须在整个程序中追踪所有的内存分配位点。

也就是说,malloc 有一些优势。如果您确定要分配的对象是普通对象(例如只保存数据的基元或结构),则使用malloc 可能会稍微快一些。 malloc 还允许您使用 realloc,而 free 不能。但老实说,在这种情况下,您最好只使用std::vectorstd::array,因为它们更安全、更易于调试,并且具有良好的编译器支持可能会被积极优化。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2017-01-01
    • 2011-04-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2013-12-01
    • 2017-12-21
    • 2011-02-16
    相关资源
    最近更新 更多