【问题标题】:Is there any good reason to use 'malloc' in C++, when there is 'new'? [duplicate]当有“新”时,是否有充分的理由在 C++ 中使用“malloc”? [复制]
【发布时间】:2011-01-25 10:30:09
【问题描述】:

可能重复:
In what cases do I use malloc vs new?

重复:In what cases do I use malloc vs new?When to use Malloc instead of New

在现实生活中,有没有人认为在 C++ 中使用“malloc”而不是“new”是合理的?

【问题讨论】:

标签: c++ malloc


【解决方案1】:

To new is C++;
To malloc is C;
To mix them is sin.

没有很好的理由这样做,而且这个问题与this one 非常相关。

【讨论】:

  • 很好,但并没有真正解决问题。
  • 不仅如此,还有一点点押韵暗示有一个很好的理由,即当你需要混合 C 和 C++ 时,例如与旧系统的接口
【解决方案2】:

new 总是调用构造函数(尽管在 POD 的情况下会发生其他情况)。有时——很少——你想处理与任何类型无关的原始内存。当您实现自己的 allocator 类时,可能会出现这种情况。即使那样,malloc 也很少是正确的做法,但有时您可能希望利用realloc 即能够更有效地调整底层存储的大小。这是一种需要malloc 来获取初始存储的场景。

原始内存的另一个实际用例是当您发现自己在实现“不可预测”的伪随机数生成器时(不要!)。为了增加生成器可用的熵,您可以使用未初始化的内存作为随机种子的基础。来自硬件中各种来源的熵对于此类操作至关重要,因此如果您确切知道自己在做什么,可能需要使用未初始化的内存(关于它的预测不多)。


为了完整起见,我应该指出,同样可以通过调用::operator new 而不是malloc 来实现。后者还检查是否可以成功分配所需的内存量,并在出现问题时调用适当的回调处理程序(参见_set_new_handler)。最后但同样重要的是,如果没有处理程序设法释放足够的内存,::operator new 将抛出 std::bad_alloc(除非将 std::nothrow 指定为第二个参数,在这种情况下将返回 0)。

【讨论】:

  • +1 这是一个很好的理由。 :)
  • 我不相信未初始化的内存是有价值的熵源。我想如果你碰巧知道在你的实现中读取未初始化的值是安全的,那么将它扔到池中并没有什么坏处,理由是“每一点都有帮助”。但是你必须将它的熵估计为 0,因为它可能总是全 0,或者它可能被恶意操纵以包含攻击者选择的值,或者诸如此类。在任何情况下,即使new char[n] 也会为您提供未初始化的内存,所以它仍然不是malloc 的情况。我想realloc 是吗,真的。
  • 哦,当然,“因为我使用的界面说我必须提供一个可以用free 释放的块”。
  • @Steve:我没有数学背景对此发表评论。但很明显,OpenSSL 的程序员认为它已经足够有用了,并且在 Debian 的某个人不小心修补了代码以初始化内存之后,OpenSSL 发出的 SSL 和 SSH 密钥不再安全。显然,记忆熵是这里的一个主要因素。几年前,这是一个重大新闻故事和一个巨大的安全漏洞。阅读:blogs.fsfe.org/tonnerre/archives/24
  • 那是不同的。问题在于将随机数据写入到缓冲区(RAND_bytes)的函数首先将缓冲区读取估计为0的熵池中。这引发了valgrind警告(读取未初始化的数据),Debian 开发人员将其“修复”在错误的位置,结果调用 RAND_add 也没有向池中读取任何内容。随机性决不依赖于未初始化的数据,但它确实依赖于不时调用 MD_update。见research.swtch.com/2008/05/…
【解决方案3】:

在 C++ 中在某种程度上合理使用 malloc 的唯一示例是创建手动内存分配方案,其中分配大量原始内存,然后创建小对象在这个缓冲区中使用placement-new。

然而,即使是这种使用也是有问题的,因为同样的目标可以而且可能应该通过使用新的或操作系统提供的分配函数来创建一个初始的大字符缓冲区,然后在其中放置新对象。

【讨论】:

    【解决方案4】:
    【解决方案5】:

    Realloc 只能用于分配的内存位置。 Realloc 最好调整内存块的大小,而不是分配新的内存块。内存分配在 C/C++ 中相对昂贵,因此这可能是性能优势。

    【讨论】:

      【解决方案6】:

      最明显的场景是与旧系统集成,这需要您传递或接受某些内存的所有权,因为您不应该混合使用 new/free 或 malloc/delete。

      我从未在 C++ 中使用过 malloc

      【讨论】:

        猜你喜欢
        • 2018-03-13
        • 1970-01-01
        • 2010-11-03
        • 1970-01-01
        • 2015-04-29
        • 2013-06-04
        • 2010-10-18
        • 2010-09-16
        • 1970-01-01
        相关资源
        最近更新 更多