操作符new(size_t)使用malloc()?

时间:2022-05-27 17:02:02

Does ::operator new(size_t) call malloc() internally, or does it use system calls / OS-specific library calls directly? What does the C++ standard say?

是:操作符new(size_t)在内部调用malloc(),还是直接使用系统调用/特定于os的库调用?c++标准怎么说?

In this answer it says that:

在这个答案里,它说:

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.

malloc()保证返回与任何标准类型对齐的地址。::操作符new(n)只保证返回一个地址对任何不大于n的标准类型对齐,如果T不是字符类型,那么new T[n]只需要返回一个对T对齐的地址。

And that suggests that new() cannot be required to call malloc().

这意味着不能要求new()调用malloc()。

Note: There's an SO question about everything operator new does other than allocation.

注意:除了分配之外,还有一个关于新操作符的SO问题。

3 个解决方案

#1


9  

The details of how operator new is implemented are property of a particular implementation of standard library - not even a compiler or operation system. I am familiar with one (gnu) and aware of 3 others - CLang, Apache and MSFT. All of them are using malloc() within operator new, because it just makes a life of library developer so much easier.

如何实现新操作符的细节是标准库的特定实现的属性——甚至不是编译器或操作系统。我熟悉一个(gnu),也知道另外三个——CLang, Apache和MSFT。它们都在操作符new中使用malloc(),因为它使库开发人员的生活变得非常简单。

If malloc() were not used, said developer would have to reimplement a lot in terms of memory allocation, and sprinkle the code heavily with OS-dependent logic to actually request memory. No one wants to do this when malloc() is already there. But by no means they are obliged to use it.

如果不使用malloc(),那么said developer将不得不重新实现大量内存分配,并在代码中大量使用与操作系统相关的逻辑来实际请求内存。当malloc()已经存在时,没有人希望这样做。但是他们并没有义务使用它。

#2


3  

It can, and usually it does.
On Windows (more specificly on VC++), the chain of calls looks like

它可以,而且通常是这样。在Windows上(更具体地说,在vc++上),调用链看起来是这样的

operator new calls malloc calls HeapAlloc

运营商new调用malloc调用HeapAlloc

HeapAlloc is a Windows API function in for allocating memory from specific heap. when the process goes up, it allocate a heap (the CRT heap) in which all the standard allocation takes memory.

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

No, it isn't obligated to call malloc. it is up to the library developers/end user developer to decide from where they want their memory from.

不,它没有义务打电话给malloc。由库开发人员/最终用户开发人员决定从哪里获取内存。

For example, I can create a mono-threaded program. usually the heap allocator locks the heap lock when allocation/deallocation takes place, in order to prevent fatal race-condition on the heap. but if my program is monothreaded, I don't have the problem.
I may choose to create my own heap with WinApi HeapCreate and pass HEAP_NO_SERIALIZE which makes the heap skip the lock. then I can use operator new with plain HeapAlloc. this is a case where I can make new work with different function then malloc.

例如,我可以创建一个单线程程序。通常堆分配器在分配/释放发生时锁住堆锁,以防止堆上致命的争用条件。但是如果我的程序是单方的,我就没有问题了。我可以选择使用WinApi HeapCreate创建自己的堆,并通过HEAP_NO_SERIALIZE,使堆跳过锁。然后,我可以使用算子new与普通HeapAlloc。在这种情况下,我可以用不同的函数来完成新的工作。

Another low level approach which is sometimes* is done is to allocate huge memory block with VirtualAlloc, then pass a re-calculated memory address anytime someone calls new.

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

(all of these approches are done pretty rarely, and from my experiance they bring minimal improvment to the execution time)

(所有这些方法都很少被采用,从我的经验来看,它们对执行时间的改善很小)

#3


2  

Yes, it may call malloc - under windows with VS and standard runtime library it does call malloc.

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

You are allowed to overload new operator and call your own allocation function. In application I work on, we have custom malloc from Doug Lea with lots of customizations for embeded systems. Windows calls malloc because it calls HeapAlloc, which is standard heap allocation function under windows. It also allows debugging allocation errors with CrtDbg api.

允许重载新的操作符并调用自己的分配函数。在我所研究的应用程序中,我们有来自Doug Lea的自定义malloc,其中有许多嵌入系统的自定义。Windows调用malloc,因为它调用HeapAlloc,这是Windows下的标准堆分配函数。它还允许使用CrtDbg api调试分配错误。

To make answer more formal I have looked up the standard and in §18.6.1.1, I found that new

使答案更正式的我抬头的标准和§18.6.1.1,我发现新的

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.

执行循环:在循环中,函数首先尝试分配请求的存储。该尝试是否涉及对标准C库函数malloc的调用,尚不明确。

so wheteher malloc is used is unspecified - it might use it or not.

因此,是否使用malloc是未知的——它可能使用它或不使用它。

#1


9  

The details of how operator new is implemented are property of a particular implementation of standard library - not even a compiler or operation system. I am familiar with one (gnu) and aware of 3 others - CLang, Apache and MSFT. All of them are using malloc() within operator new, because it just makes a life of library developer so much easier.

如何实现新操作符的细节是标准库的特定实现的属性——甚至不是编译器或操作系统。我熟悉一个(gnu),也知道另外三个——CLang, Apache和MSFT。它们都在操作符new中使用malloc(),因为它使库开发人员的生活变得非常简单。

If malloc() were not used, said developer would have to reimplement a lot in terms of memory allocation, and sprinkle the code heavily with OS-dependent logic to actually request memory. No one wants to do this when malloc() is already there. But by no means they are obliged to use it.

如果不使用malloc(),那么said developer将不得不重新实现大量内存分配,并在代码中大量使用与操作系统相关的逻辑来实际请求内存。当malloc()已经存在时,没有人希望这样做。但是他们并没有义务使用它。

#2


3  

It can, and usually it does.
On Windows (more specificly on VC++), the chain of calls looks like

它可以,而且通常是这样。在Windows上(更具体地说,在vc++上),调用链看起来是这样的

operator new calls malloc calls HeapAlloc

运营商new调用malloc调用HeapAlloc

HeapAlloc is a Windows API function in for allocating memory from specific heap. when the process goes up, it allocate a heap (the CRT heap) in which all the standard allocation takes memory.

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

No, it isn't obligated to call malloc. it is up to the library developers/end user developer to decide from where they want their memory from.

不,它没有义务打电话给malloc。由库开发人员/最终用户开发人员决定从哪里获取内存。

For example, I can create a mono-threaded program. usually the heap allocator locks the heap lock when allocation/deallocation takes place, in order to prevent fatal race-condition on the heap. but if my program is monothreaded, I don't have the problem.
I may choose to create my own heap with WinApi HeapCreate and pass HEAP_NO_SERIALIZE which makes the heap skip the lock. then I can use operator new with plain HeapAlloc. this is a case where I can make new work with different function then malloc.

例如,我可以创建一个单线程程序。通常堆分配器在分配/释放发生时锁住堆锁,以防止堆上致命的争用条件。但是如果我的程序是单方的,我就没有问题了。我可以选择使用WinApi HeapCreate创建自己的堆,并通过HEAP_NO_SERIALIZE,使堆跳过锁。然后,我可以使用算子new与普通HeapAlloc。在这种情况下,我可以用不同的函数来完成新的工作。

Another low level approach which is sometimes* is done is to allocate huge memory block with VirtualAlloc, then pass a re-calculated memory address anytime someone calls new.

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

(all of these approches are done pretty rarely, and from my experiance they bring minimal improvment to the execution time)

(所有这些方法都很少被采用,从我的经验来看,它们对执行时间的改善很小)

#3


2  

Yes, it may call malloc - under windows with VS and standard runtime library it does call malloc.

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

You are allowed to overload new operator and call your own allocation function. In application I work on, we have custom malloc from Doug Lea with lots of customizations for embeded systems. Windows calls malloc because it calls HeapAlloc, which is standard heap allocation function under windows. It also allows debugging allocation errors with CrtDbg api.

允许重载新的操作符并调用自己的分配函数。在我所研究的应用程序中,我们有来自Doug Lea的自定义malloc,其中有许多嵌入系统的自定义。Windows调用malloc,因为它调用HeapAlloc,这是Windows下的标准堆分配函数。它还允许使用CrtDbg api调试分配错误。

To make answer more formal I have looked up the standard and in §18.6.1.1, I found that new

使答案更正式的我抬头的标准和§18.6.1.1,我发现新的

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.

执行循环:在循环中,函数首先尝试分配请求的存储。该尝试是否涉及对标准C库函数malloc的调用,尚不明确。

so wheteher malloc is used is unspecified - it might use it or not.

因此,是否使用malloc是未知的——它可能使用它或不使用它。