::operator new(size_t) 是否使用 malloc()?

Does ::operator new(size_t) use malloc()?

::operator new(size_t)是在内部调用malloc(),还是直接使用系统调用/OS特定的库调用? C++ 标准怎么说?

this answer 中说:

malloc() is guaranteed to return an address aligned for any standard type. ::operator new(n) is only guaranteed to return an address aligned for any standard type no larger than n, and if T isn't a character type then new T[n] is only required to return an address aligned for T.

这表明 new() 不需要调用 malloc()

注意:关于 operator new 所做的 其他 除分配之外的所有事情,都有一个 SO question

是的,它可能会调用 malloc - 在 windows 下使用 VS 和标准运行时库它会调用 malloc

您可以重载 new 运算符并调用您自己的分配函数。在我处理的应用程序中,我们有来自 Doug Lea 的定制 malloc,其中包含许多针对嵌入式系统的定制。 Windows调用malloc是因为它调用了HeapAlloc,这是windows下的标准堆分配函数。它还允许使用 CrtDbg api.

调试分配错误

为了让回答更正式,我查阅了标准,在 §18.6.1.1 中,我发现 new

Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified.

因此未指定是否使用 malloc - 它可能使用或不使用它。

可以,而且通常会。
在 Windows 上(更具体地说在 VC++ 上),调用链看起来像

operator new 调用 malloc 调用 HeapAlloc

HeapAlloc 是一个 Windows API 函数,用于从特定堆分配内存。 当进程上升时,它分配一个堆(CRT堆),所有标准分配都在其中占用内存。

不,它没有义务调用 malloc。由图书馆 developers/end 用户开发人员决定他们想要从哪里获得记忆。

例如,我可以创建一个mono-threaded程序。通常堆分配器会在 allocation/deallocation 发生时锁定堆锁,以防止堆上出现致命的 race-condition。 但是如果我的程序是单线程的,我就没有问题。
我可以选择使用 WinApi HeapCreate 创建我自己的堆并传递 HEAP_NO_SERIALIZE 这使得堆跳过锁。然后我可以将 operator new 与纯 HeapAlloc 一起使用。在这种情况下,我可以让 new 使用与 malloc.

不同的功能

另一种有时*完成的低级方法是使用 VirtualAlloc 分配巨大的内存块,然后在有人调用 new 时传递一个 re-calculated 内存地址。

(所有这些方法都很少完成,根据我的经验,它们对执行时间的改进微乎其微)

如何 operator new 实现的细节是 属性 标准库的特定实现 - 甚至不是编译器或操作系统。我熟悉一个 (gnu) 并了解其他 3 个——CLang、Apache 和 MSFT。他们都在 operator new 中使用 malloc(),因为这让图书馆开发人员的生活变得如此轻松。

如果不使用 malloc(),表示开发人员将不得不在内存分配方面重新实现很多,并在代码中大量使用 OS-dependent 逻辑来实际请求内存。当 malloc() 已经存在时,没有人愿意这样做。但绝不是他们必须使用它。