假设我有 10 kB 的堆,并混合了 C 和这样的C++代码。
char* block1 = malloc(5*1024); //allocate 5
char* block2 = new[](4*1024); // allocate 4
是否有 C 堆和 C++ 堆,或者只是两者通用的单个堆?所以"新"知道堆的前 5 kb 已经分配了?
可能有也可能没有单独的C和C++堆。你不能编写一个符合C++的程序来区分,所以这完全取决于实现。
该标准描述了operator new
默认行为的第一步,如下所示:
执行循环:在循环中,函数首先尝试 分配请求的存储。尝试是否涉及调用 C 标准库函数 malloc 或 aligned_alloc 是 未指定。[新.删除.单曲]/4.1.
对于malloc
本身,该标准说:"[aligned_alloc
、calloc
、malloc
和realloc
]不要尝试通过调用::operator new()
来分配存储" [c.malloc]/3。
所以目的是可以从operator new
调用malloc
,但这不是必需的。
实际上,operator new
调用malloc
.
内存分配的工作方式是,用户空间程序首先通过系统调用(*nix 上的 sbrk 或 mmap(从操作系统请求一个或多个内存页。 这通常是由包含在"C 库"中的 malloc 实现(有几个(完成的。然后,此malloc实现管理它(成功(请求的所有页面。这是在用户空间中完成的。
回到你的问题:::运算符 new的大多数实现只会中继到 malloc。但是您始终可以使用不同的分配器实现,甚至可以在程序中混合使用多个分配器(请参阅:内存池(。
这就是为什么标准要求你不要混合malloc/free和new/delete的原因。
*(许多malloc实现都存在许多小对象的问题(这在C++中很常见(,这是更改分配器的一个很好的理由。
一个有效的实现应该是直接使用系统调用brk()
/mmap()
而不是通过malloc()
。 虽然看看 gnu 实现,但事实并非如此。它在内部使用malloc()
。