非常适合以“深入剖析 new
和 delete
的使用与底层实现”为主题撰写 C/C++ 系列中的内存管理专章。以下是专为你定制的详细教程文章提纲与内容,适合用于技术博客、系列连载或视频脚本中。
🔍 内存管理 –《Hello C++ World!》(8)
(C/C++) 深入剖析 new
和 delete
的使用与底层实现
📚 目录
new
和delete
是什么?malloc
vsnew
:本质区别new/delete
的使用范式- 底层实现解析(C++ operator new)
- 自定义
operator new
和operator delete
- C++ 中构造与析构的关系
- new[] 与 delete[] 背后的机制
- C++17/20 中的新特性:aligned new、placement new
- 面试延伸:new 和 delete 到底做了什么?
- 实战建议与最佳实践
1. new
和 delete
是什么?
new
和 delete
是 C++ 中的运算符,用于 动态分配和释放内存,其本质是对 malloc/free
的封装加上 对象构造/析构。
int* p = new int(10); // 分配并初始化
delete p; // 释放并调用析构函数
2. malloc
vs new
:本质区别
特性 | malloc/free | new/delete |
---|---|---|
所属语言 | C / C++ | C++ 专用 |
内存分配 | 是 | 是 |
构造函数调用 | 否 | ✅ 自动调用构造函数 |
类型安全 | 否,返回 void* | ✅ 强类型 |
操作符重载 | 否 | ✅ 可重载 operator new |
异常安全 | 返回 NULL | 抛出 std::bad_alloc |
3. new/delete
的使用范式
普通用法:
MyClass* obj = new MyClass(); // 构造函数自动调用
delete obj; // 析构函数自动调用
数组用法:
int* arr = new int[100]; // 分配100个int空间
delete[] arr; // 必须使用 delete[]
4. 底层实现解析
// 实际上,new 运算符分为两步:
1. 分配内存:调用 ::operator new()
2. 构造对象:调用构造函数(placement new)
// delete 运算符也分为两步:
1. 调用析构函数
2. 释放内存:调用 ::operator delete()
对应伪代码:
// new T(args) 展开如下:
void* mem = operator new(sizeof(T)); // 第一步:分配内存
T* obj = new (mem) T(args); // 第二步:placement new
5. 自定义 operator new
和 operator delete
你可以在类中重载 operator new
来控制分配策略:
class MyClass {
public:
static void* operator new(size_t size) {
std::cout << "MyClass::operator new\n";
return ::operator new(size); // 默认分配
}
static void operator delete(void* ptr) {
std::cout << "MyClass::operator delete\n";
::operator delete(ptr);
}
};
6. 构造与析构关系(隐藏细节)
new MyClass(); // 隐含:malloc + placement new
delete ptr; // 隐含:调用析构函数 + free
注意:如果构造函数抛异常,则
operator delete
会自动调用清理资源!
7. new[] 与 delete[] 背后的机制
数组 new[]
分配的内存结构中会 额外存储元素数量信息,以便 delete[] 正确调用每个元素的析构函数。
示例说明:
MyClass* arr = new MyClass[3];
// 内部可能会:存储 3,然后构造3个对象
delete[] arr;
// 内部:先析构 arr[2], arr[1], arr[0],再释放内存
8. C++ 新特性:aligned new、placement new
C++17 对齐分配:
void* p = ::operator new(64, std::align_val_t(64));
::operator delete(p, std::align_val_t(64));
Placement new:
char buffer[sizeof(MyClass)];
MyClass* obj = new (buffer) MyClass(); // 在 buffer 上构造对象
obj->~MyClass(); // 手动析构
9. 面试延伸:new/delete 底层调用流程
new = operator new + 构造函数
delete = 析构函数 + operator delete
内存池、自定义分配器等高级性能优化技术,都是通过重载 operator new/delete
实现的。
10. 实战建议与最佳实践
✅ 使用 new/delete 替代 malloc/free,获取构造/析构语义
✅ 始终成对使用 new/delete 或 new[]/delete[]
❌ 切勿混用 new 与 free(或 malloc 与 delete)
✅ 对性能要求高时,考虑重载 new 实现对象池
✅ 可借助智能指针避免手动 delete(如 std::unique_ptr
)
📌 小结
new
和 delete
是 C++ 的内存管理核心。相比 malloc/free
,它们具备:
- 类型安全
- 构造析构自动调用
- 可自定义操作符重载
- 与现代 C++ 兼容性强(如智能指针、RAII)
理解其底层实现,是迈向性能优化、内存调优、内存池设计的重要一步!
发表回复