::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()
已经存在时,没有人愿意这样做。但绝不是他们必须使用它。
::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 thann
, and ifT
isn't a character type then newT[n]
is only required to return an address aligned forT
.
这表明 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()
已经存在时,没有人愿意这样做。但绝不是他们必须使用它。