::operator new(size_t)使用malloc()吗?

18
::operator new(size_t)会在内部调用malloc(),还是直接使用系统调用/特定于操作系统的库调用?C++标准有什么说法?
this answer中提到:

malloc()保证返回对于任何标准类型都对齐的地址。::operator new(n)仅保证返回对于任何不大于n的标准类型都对齐的地址,如果T不是字符类型,则只需要为T对齐即可。

这表明new()不能要求调用malloc()
注意:有一个关于operator new除了分配之外的所有操作的SO question

类似的问题是:是否可以使用free()而不是delete释放使用new关键字分配的指针。 - i486
3个回答

28
< p >如何实现operator new的详细信息是特定标准库实现的属性 - 甚至不是编译器或操作系统。我熟悉其中一个(gnu),并了解另外3个 - CLang,Apache和MSFT。所有这些都在operator new中使用malloc(),因为这使得库开发人员的生活变得更加轻松。

如果不使用malloc(),则该开发人员将不得不重新实现大量关于内存分配的内容,并且在代码中大量使用依赖于操作系统的逻辑来实际请求内存。当已经有malloc()时,没有人想要这样做。但是他们并不一定必须使用它。


5
它可以,通常也确实如此。
在Windows上(更具体地说是VC ++),调用链如下:

operator new 调用 mallocmalloc 调用 HeapAlloc

HeapAlloc 是用于从特定堆中分配内存的 Windows API 函数。 当进程启动时,它会分配一个堆(CRT 堆),所有标准分配都占用该内存。

不,它并不强制调用 malloc。这取决于库开发人员/最终用户开发人员决定从哪里获取他们的内存。

例如,我可以创建一个单线程程序。通常,堆分配器在进行分配/释放时会锁定堆锁,以防止堆上的致命竞争条件。 但如果我的程序是单线程的,则我没有这个问题。
我可以选择使用 WinApi HeapCreate 创建自己的堆,并传递 HEAP_NO_SERIALIZE,使堆跳过锁定。然后我就可以使用纯粹的 HeapAlloc 使用 operator new。 这是一种情况,我可以让 new 使用与 malloc 不同的函数。

另一种有时*使用的低级方法是使用 VirtualAlloc 分配大内存块,然后每次有人调用 new 时传递重新计算的内存地址。

(所有这些方法都很少使用,并且根据我的经验,它们对执行时间带来了极小的改善)


2

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

您可以重载new运算符并调用自己的分配函数。在我所在的应用程序中,我们使用Doug Lea的自定义malloc,针对嵌入式系统进行了许多定制。Windows调用malloc,因为它调用HeapAlloc,在Windows下是标准堆内存分配函数。它还允许使用CrtDbg API调试分配错误。

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

执行一个循环:在循环内部,函数首先尝试分配所请求的存储空间。无论尝试是否涉及调用标准C库函数malloc都是未指定的

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


它必须调用malloc吗? - einpoklum
1
当然不是@einpoklum。这是实现细节。此外,答案在技术上并不正确 - 这取决于您使用的标准库,而不是编译器或操作系统。但是,对于任何库实现者来说,重用已经可用的malloc()功能比自己编写特定于操作系统的代码更有意义。 - SergeyA
@SergeyA:从技术上讲,标准谈论的是“一个实现”。如果你通过从一个地方获取编译器、从另一个地方获取标准库以及从第三个地方获取链接器来构建自己的实现,那么你就是一个实现者,并且需要负责确保它正确。大多数人从单一来源获取他们的实现(并称其为“编译器”)。 - Martin Bonner supports Monica
@MartinBonner,这显然不是一个技术上正确的术语。例如,CLang作为编译器发行时没有std库(但提供独立的库),而Apache提供了一个没有编译器的库。 - SergeyA
“不是技术上正确的术语”是什么?“实现”是什么意思?标准的第一句话是:“本国际标准规定了C++编程语言的实现要求。”库是该实现的一部分。 - Martin Bonner supports Monica
@MartinBonner,当然不是。正如你在评论中所说的那样,“编译器”并不是指“实现”的正确术语。虽然我觉得我们在纠结于一些微小的问题。 - SergeyA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接