繁体   English   中英

为什么我更喜欢在堆上使用免费存储?

[英]Why should I prefer using the free store over the heap?

在Exceptional C ++中,Herb Sutter在第35项中写了一条准则:

首选使用免费商店(新建/删除)。 避免使用堆(malloc / free)。

我为什么要?

如果实现选择使用malloc实现new ,则可能会产生开销,因此就性能而言,这似乎是一个糟糕的建议。

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或处理零大小的请求等),但是我希望这有助于解释newmalloc的不同之处。

那么,为什么要在malloc使用new呢? 好吧,有几个原因:

  • 更安全。 使用malloc可以忘记检查返回类型是否为空指针,或者可以请求错误的存储空间,或者可以忘记在对象上调用构造函数,或者如果构造函数抛出例外等

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

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

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

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM