在 C++ 开发中,动态内存管理是重中之重!new/delete
和 malloc/free
都是用来动态申请和释放内存的,但它们有本质的区别。今天我们就来彻底搞懂它们的区别,避免内存泄漏和 undefined behavior!
✅ 都是动态内存管理:在堆(heap)上分配内存,需要手动释放,否则会导致内存泄漏。
✅ 返回指针:申请成功时返回内存地址,失败时 malloc
返回 NULL
,new
抛出 std::bad_alloc
异常(除非用 nothrow
版本)。
特性 | new / delete (C++) | malloc / free © |
---|---|---|
语言 | C++ 关键字 | C 标准库函数 |
内存计算 | 自动计算大小(new int ) |
需手动计算(malloc(sizeof(int)) ) |
初始化 | 调用构造函数(new ) / 析构函数(delete ) |
仅分配/释放内存,不调用构造/析构 |
返回类型 | 返回具体类型指针(int* ) |
返回 void* ,需强制转换 |
失败处理 | 默认抛异常(bad_alloc ) |
返回 NULL |
重载 | 可重载 operator new |
不可重载 |
内存不足处理 | 可自定义 new_handler |
只能检查返回值 |
数组支持 | new[] / delete[] |
需手动计算数组大小 |
new
会调用构造函数,malloc
不会:class A {
public:
A() { std::cout << "A constructed!" << std::endl; }
~A() { std::cout << "A destroyed!" << std::endl; }
};
A *p1 = new A; // 调用构造函数
A *p2 = (A*)malloc(sizeof(A)); // 不调用构造函数!
free(p2); // 不调用析构函数!
delete p1; // 调用析构函数
⚠️ 如果用 malloc
申请类对象,对象不会被初始化,可能导致崩溃!delete
会调用析构函数,free
不会:int *p1 = new int(10);
delete p1; // 正确释放
int *p2 = (int*)malloc(sizeof(int));
free(p2); // 正确释放
// ❌ 错误示范:
int *p3 = new int[10];
free(p3); // 未调用析构函数,可能导致内存泄漏(如果数组元素是对象)
绝对不能混用!new
的内存必须用 delete
释放,malloc
的内存必须用 free
释放!new[]
和 delete[]
用于动态数组:int *arr1 = new int[10]; // 分配 10 个 int
delete[] arr1; // 正确释放
int *arr2 = (int*)malloc(10 * sizeof(int));
free(arr2); // 正确释放
⚠️ 如果用 delete
释放 new[]
分配的数组,行为未定义(UB)!✔ C++ 代码一律用 new/delete
(更安全,支持构造/析构)
✔ C 代码或与 C 库交互时用 malloc/free
✔ 避免混用!否则可能导致内存泄漏或崩溃
场景 | 推荐方式 |
---|---|
C++ 单对象 | new / delete |
C++ 数组 | new[] / delete[] |
C 代码 | malloc / free |
兼容 C 和 C++ | 用 malloc + 手动初始化(不推荐) |
面试高频问题:
new
和 malloc
的区别?(答:构造/析构、类型安全、异常处理)delete
和 free
的区别?(答:是否调用析构函数)free
释放 new
的内存?(答:绝对不能!)