# A06 — new/delete 和 malloc/free: C++ memory management的Difference
**金句**: new 不是 malloc, delete 不是 free — 它们不只是allocate, 还有构造和析构.
—
## new 和 malloc 的Essential Difference
“`
new 和 malloc 的区别:
malloc:
– C 库函数
– 只分配内存,不初始化
– 返回 void*
– 失败返回 NULL
new:
– C++ 关键字
– 分配内存 + 调用构造函数
– 返回具体类型的指针(不需要类型转换)
– 失败抛出 std::bad_alloc
// malloc 示例
int *p = (int*)malloc(sizeof(int));
*p = 42; // 必须手动初始化
// new 示例
int *p = new int(42); // 分配 + 初始化
“`
“`
new 的底层实现:
void* operator new(size_t size) {
if (size == 0) size = 1;
// 尝试分配
void *p = malloc(size);
// 分配失败,调用 new_handler
while (p == nullptr) {
std::new_handler h = std::get_new_handler();
if (h) (*h)();
else throw std::bad_alloc();
p = malloc(size);
}
return p;
}
new 实际上调用 malloc!
delete 实际上调用 free!
“`
—
## new 和 delete 对对象的Role
“`
new 对对象:
class A {
int x;
public:
A(int v) : x(v) {}
};
A *p = new A(10);
等价于:
1. void *temp = operator new(sizeof(A)); // malloc
2. A *p = static_cast(temp);
3. p->A(10); // 调用构造函数
delete 对对象:
delete p;
等价于:
1. p->~A(); // 调用析构函数
2. operator delete(p); // free
构造和析构是 new/delete 和 malloc/free 的本质区别!
“`
“`
数组的 new[] 和 delete[]:
A *arr = new A[10]; // 分配 10 个 A 对象
delete[] arr; // 销毁 10 个对象
等价于:
1. A *arr = (A*)operator new[] (10 * sizeof(A));
2. 构造 10 个对象
3. 调用 10 次析构函数
4. operator delete[] (arr)
注意:
delete[] 必须和 new[] 配对
用 delete(不带[])销毁数组会导致 UB
“`
—
## placement new
“`
placement new:在指定地址构造对象
#include
char buf[sizeof(A)];
A *p = new(buf) A(10); // 在 buf 上构造 A
等价于:
void *temp = buf;
A *p = static_cast(temp);
p->A(10);
用途:
– 预先分配的内存上构造对象
– 内存池
– 对象构造/析构灵活控制
显式析构(placement delete):
p->~A(); // 只调用析构,不释放内存
“`
—
## operator new 可以重载
“`
可以自定义 operator new:
class MyClass {
public:
static void* operator new(size_t size) {
// 自定义分配逻辑
// 比如从对象池分配
return pool.allocate(size);
}
static void operator delete(void* p) {
// 自定义释放逻辑
pool.deallocate(p);
}
};
所有 MyClass 的 new 都走这个函数。
全局 operator new 可以被所有类型使用。
“`
—
## Summary
– **malloc**: 只allocate内存, 不initialize, return void*
– **new**: allocate内存 + 调用构造函数, return具体Type指针, 失败抛exception
– **operator new**: 底层调用 malloc, new 是 operator new + 构造
– **delete**: 调用析构 + operator delete (底层 free)
– **new[]/delete[]**: 构造/析构数组, 必须配对使用
– **placement new**: 在指定地址构造对象, 不allocate内存
**下篇预告 (A07) **: What is 内存池? 预先allocate大块内存, 按需allocate — 为什么游戏服务器常用内存池来避免 malloc.
—
*关注公众号”AI不着急”, 回复”资料”obtain内存学习路线图. *
Comments