::operator new(size_t) 是不是使用 malloc()?
Posted
技术标签:
【中文标题】::operator new(size_t) 是不是使用 malloc()?【英文标题】:Does ::operator new(size_t) use malloc()?::operator new(size_t) 是否使用 malloc()? 【发布时间】:2016-04-21 04:29:53 【问题描述】:::operator new(size_t)
是在内部调用malloc()
,还是直接使用系统调用/特定于操作系统的库调用? C++ 标准是怎么说的?
在this answer 中说:
malloc()
保证返回与任何标准类型对齐的地址。::operator new(n)
仅保证返回与不大于n
的任何标准类型对齐的地址,如果T
不是字符类型,则只需 newT[n]
返回与T
对齐的地址.
这表明不能要求new()
调用malloc()
。
注意:question 关于 operator new
所做的所有事情其他,而不是分配。
【问题讨论】:
类似的问题是:是否可以使用free()
而不是delete
来释放使用new
关键字分配的指针。
【参考方案1】:
operator new
如何实现的细节是标准库的特定实现的属性——甚至不是编译器或操作系统。我熟悉一个(gnu)并知道其他 3 个 - CLang、Apache 和 MSFT。他们都在operator new
中使用malloc()
,因为它让库开发人员的生活变得更加轻松。
如果不使用malloc()
,开发人员将不得不在内存分配方面重新实现很多,并在代码中大量使用依赖于操作系统的逻辑来实际请求内存。当malloc()
已经存在时,没有人愿意这样做。但绝不是他们有义务使用它。
【讨论】:
【参考方案2】:可以,而且通常可以。 在 Windows 上(更具体地说,在 VC++ 上),调用链看起来像
operator new
打电话给malloc
打电话给HeapAlloc
HeapAlloc
是一个 Windows API 函数,用于从特定堆分配内存。
当进程启动时,它会分配一个堆(CRT 堆),所有标准分配都在其中占用内存。
不,没有义务调用 malloc。由库开发人员/最终用户开发人员决定他们想要从哪里获得内存。
例如,我可以创建一个单线程程序。通常堆分配器在分配/释放发生时锁定堆锁,以防止堆上的致命竞争条件。
但如果我的程序是单线程的,我就没有问题。
我可以选择使用 WinApi HeapCreate
创建自己的堆并传递 HEAP_NO_SERIALIZE
,这会使堆跳过锁。然后我可以将operator new
与普通的HeapAlloc
一起使用。在这种情况下,我可以让 new
使用与 malloc
不同的功能。
另一种有时*的低级方法是使用VirtualAlloc
分配巨大的内存块,然后在有人调用new
时传递重新计算的内存地址。
(所有这些方法都很少完成,根据我的经验,它们对执行时间的改善很小)
【讨论】:
【参考方案3】:是的,它可能会调用 malloc - 在带有 VS 和标准运行时库的 Windows 下,它确实会调用 malloc
。
您可以重载 new 运算符并调用您自己的分配函数。在我工作的应用程序中,我们有来自 Doug Lea 的自定义 malloc,其中包含许多针对嵌入式系统的自定义。 windows调用malloc是因为它调用了heapAlloc,这是windows下的标准堆分配函数。它还允许使用 CrtDbg api 调试分配错误。
为了让答案更正式,我查阅了标准,在 §18.6.1.1 中,我发现 new
执行一个循环:在循环内,函数首先尝试 分配请求的存储空间。 尝试是否涉及调用 标准 C 库函数 malloc 未指定。
因此未指定是否使用 malloc - 它可能会使用它。
【讨论】:
而且必须它调用malloc? @einpoklum,当然不是。这是实现细节。此外,答案在技术上并不正确——重要的是您使用什么标准库,而不是什么编译器或操作系统。但是,对于任何库实现者来说,重用 malloc() 的现有功能而不是自己编写特定于操作系统的编码是有意义的。 @SergeyA:从技术上讲,该标准谈论的是“实现”。如果您通过从一个地方获取编译器、从另一个地方获取标准库和从第三方获取链接器来构建自己的实现,那么您就是实现者并负责正确执行。大多数人从单一来源获得他们的实现(并称其为“编译器”)。 @MartinBonner,这在技术上肯定不是一个正确的术语。例如,作为编译器的 CLang 没有 std 库(同时提供一个独立的库),而 Apache 提供了一个没有编译器的库。 什么是“技术上不正确的术语”? “实施”?该标准的第一句话是“本国际标准规定了 C++ 编程语言的实现要求”。该库是该实现的一部分。以上是关于::operator new(size_t) 是不是使用 malloc()?的主要内容,如果未能解决你的问题,请参考以下文章
C# 中的“var”是不是类似于 C 中的“size_t”?
C++内存管理(new operator/operator new/operator delete/placement new)
c++ new operator和operator new,delete operator和operator delete