1. 内存管理函数的层次
从下图中可以看到,C++程序员处于的位置是最上层的Applications,用的最多的是new,new[],如果用容器,则内存基本不用管理。其次也可以调用malloc。至于最底层的操作系统级别的API,没有可移植性。它们之间的调用关系如上图的箭头所示。
2. Memory primitives分类
| 分配 | 释放 | 所属 | 可否重载 |
|---|---|---|---|
malloc |
free |
C函数 |
否 |
new |
delete |
C++表达式 |
否 |
::operator new() |
::operator delete() |
C++函数 |
可 |
allocator<T>::allocate() |
allocator<T>::deallocate() |
STL分配器 |
可以自己设计搭配容器 |
1 | void primitives_sample() |
3. new的初步探究
c++的程序员基本都会用new来为对象分配一个堆内存,并且new会调用对应的构造函数,构造函数是用来初始化对象的,所以总结出new的功能是:
- 在堆中分配一块指定对象大小的内存
- 将返回的指针转换为指向对象类型的指针
- 通过指针调用对象相应的构造函数

4. 测试new的调用流程
1 | struct A |
上面的4张图是在MSVC中反汇编的运行时代码。从第1张图可以看出,new调用了operator new,从第3张图可以看出,operator new内部调用了malloc。实际上编译器是在new的地方调用了对应的构造函数,并不是在new的内部,new只是编译器识别的一个标识符,并不是函数,编译器看到new后会malloc,然后调用构造函数。
VS2019可以看到operator new的源码:
1 | _CRT_SECURITYCRITICAL_ATTRIBUTE |
上面的operator new的作用是调用malloc分配内存。当malloc成功后直接返回。当malloc失败后,并不会再次malloc,而是调用_callnewh() new_handler(),这个函数的作用是向自己定义的函数索取内存,所以new_handler可以理解为释放一些缓存,调用完new_handler后,可能释放了内存,这个时候再尝试调用malloc获取内存。
5. delete的初步探究

6. 测试delete的调用流程
1 | using namespace std; |