1

标准 C++ 的哪些部分将调用 malloc/free 而不是 new/delete?

这篇 MSDN 文章列出了调用 malloc/free 而不是 new/delete 的几种情况:http: //msdn.microsoft.com/en-us/library/6ewkz86d.aspx

我想知道这个列表是否是(按好坏的递增顺序和可能性的递减顺序):

  1. 对于其他常见的实现是正确的
  2. 详尽无遗
  3. 由 C++ 标准的某些部分保证

上下文是我想替换全局 new/delete 并且想知道如果我这样做了我会错过哪些分配。

4

3 回答 3

1

一个新的基本上是一个包装的malloc。允许编译器随意使用 stdio 函数,例如,如果您尝试实现自己的 memcpy,您会得到一些奇怪的递归。如果编译器看到您复制的数量超过一定数量(比如一个愚蠢的逐位复制构造函数),它将使用 memcpy。

所以是的,new 是一个谎言,new 的意思是“分配一些内存并在那里构造一些东西,让我把它写成一个东西”,如果你分配一个浮点数组,说它们是未初始化的,可能会直接使用 malloc。

请注意,我可能会说,我不确定这些天它们是否设置为零:P

无论如何,所有编译器优化('除了复制省略和其他返回值优化的东西——但这是唯一的例外)对你来说都是不可见的,这就是重点。该程序无法判断它是否已优化,您必须对其进行计时。例如:

(x*10)/2

如果编译器不知道 x 的范围,这将不会被优化,因为 x*10 可能会溢出,但 x*5 可能不会。所以如果它优化它会改变结果。

if(x>0 && x<10) {
    (x*10)/2
} 

将变为 x*5 因为编译器非常聪明(远不止于此)看到“x*10 不可能溢出,所以 x*5 是安全的。”

如果您定义了全局 new/delete,则编译器无法优化,因为它不知道这样做不会产生任何影响。如果你定义你自己的一切,它“简化”到 malloc/free 将会消失。

笔记:_

我故意忽略了 malloc 和类型安全的东西。这不相关。

编译器假定 malloc、free、memcpy 等都是超级优化的,并且仅在安全的情况下使用它们 - 如上所述。邮件列表中有一个 GCC 线程,在某处我了解到 memcpy 的东西。

于 2013-10-18T16:36:04.993 回答
1

我想知道这个列表是否是(按好坏的递增顺序和可能性的递减顺序):

1. True for other common implementations
2. Exhaustive
3. Guaranteed by some part of the C++ standard

我想说你不能从那个列表(我想是在备注部分给出的那个)中真正看出除了 MS 之外的其他 C++ 实现。

C++ 实现可以任意使用任何操作系统提供的系统调用。所以你所有三个问题的答案都是:不。

至于在编译器 ABI 的 C++ 特定部分的实现中使用malloc()vs : 我认为您可以假设 C++ 特定的实现使用或放置 new 用于任何分配器实现。 如果那些列出的方法使用(最不可能)或内部分配内存对于 C++ 标准库实现的用户来说并不重要。new()
new()
new()malloc()

注意:
如果您在计划覆盖的背景下询问new(),或者使用placement new 为程序上下文中的所有内存分配提供您自己的内存分配机制:那不是要走的路!
您必须提供自己的malloc(),free()等版本。人。然后。例如,当将 GCC 与 结合使用时newlib,您可以使用适当的存根。

于 2013-10-18T16:43:17.590 回答
-2

Calloc 和 malloc 比 new 和 delete 低得多。首先 malloc 和 calloc 是不安全的,因为你可以在任何你想要的类型上使用强制转换,并且对该内存中的数据的访问是不受控制的。(你最终可能会在别人的内存上写)如果你正在做一些真正的低级编程,你将不得不使用 malloc 和 calloc。如果您是普通程序员,只需使用 new 和 delete 就容易多了。为什么需要精准实施?(我不得不说实施取决于因为有很多不同的)

于 2013-10-18T16:35:44.090 回答