C++中 newdelete 与 mallocfree 的异同详解
C++中 new/delete 与 malloc/free 的异同详解
在 C++ 开发中,动态内存管理是重中之重!new/delete
和 malloc/free
都是用来动态申请和释放内存的,但它们有本质的区别。今天我们就来彻底搞懂它们的区别,避免内存泄漏和 undefined behavior!💡
1. 相同点
✅ 都是动态内存管理:在堆(heap)上分配内存,需要手动释放,否则会导致内存泄漏。
✅ 返回指针:申请成功时返回内存地址,失败时 malloc
返回 NULL
,new
抛出 std::bad_alloc
异常(除非用 nothrow
版本)。
2. 核心区别(重点!面试常考!)
特性 | 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[] | 需手动计算数组大小 |
3. 关键细节(必看!)
(1)初始化问题
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
申请类对象,对象不会被初始化,可能导致崩溃!
(2)内存释放问题
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
释放!
(3)数组处理
new[]
和delete[]
用于动态数组:
⚠️ 如果用int *arr1 = new int[10]; // 分配 10 个 int delete[] arr1; // 正确释放 int *arr2 = (int*)malloc(10 * sizeof(int)); free(arr2); // 正确释放
delete
释放new[]
分配的数组,行为未定义(UB)!
4. 如何选择?
✔ C++ 代码一律用 new/delete
(更安全,支持构造/析构)
✔ C 代码或与 C 库交互时用 malloc/free
✔ 避免混用!否则可能导致内存泄漏或崩溃
5. 总结(背下来!)
场景 | 推荐方式 |
---|---|
C++ 单对象 | new / delete |
C++ 数组 | new[] / delete[] |
C 代码 | malloc / free |
兼容 C 和 C++ | 用 malloc + 手动初始化(不推荐) |
📌 面试高频问题:
new
和malloc
的区别?(答:构造/析构、类型安全、异常处理)delete
和free
的区别?(答:是否调用析构函数)- 能否用
free
释放new
的内存?(答:绝对不能!)