C++ 中 new/delete 与 malloc/free 完全详解
一、new/delete 与 malloc/free 的区别
| 特性 |
new/delete |
malloc/free |
| 属于 |
C++语言 |
C语言 |
| 申请的内存区 |
堆(Heap) |
堆(Heap) |
| 返回类型 |
指向对象类型的指针(自动转换) |
void*,需手动强制转换类型 |
| 是否调用构造函数 |
是(调用构造函数) |
否(只分配内存,不调用构造函数) |
| 是否调用析构函数 |
是(调用析构函数) |
否 |
| 申请失败 |
抛出异常(std::bad_alloc) |
返回 NULL |
二、详细解释
1. malloc/free(C语言风格)
malloc(size_t size):申请一块连续的内存区域,大小为 size 字节。
- 返回
void*,需要强制类型转换成需要的指针类型。
- 不会调用对象的构造函数,只是单纯分配内存。
free(void* ptr):释放由 malloc 分配的内存,不调用析构函数。
使用场景:
- 兼容 C 的项目
- 只需要原始内存、不需要对象初始化时
2. new/delete(C++风格)
new Type(args):分配内存 + 调用构造函数。
delete ptr:调用析构函数 + 释放内存。
- 可以分配单个对象,也可以分配数组对象(
new Type[n])。
使用场景:
- 需要构造和析构管理的 C++ 对象
- 更安全、更易用,符合 C++ RAII 风格
三、常见使用示例
1. malloc/free 示例
cpp
复制代码
#include <cstdlib> // for malloc/free
#include <iostream>
struct MyStruct {
int x;
float y;
};
int main() {
// malloc 分配内存
MyStruct* p = (MyStruct*)malloc(sizeof(MyStruct));
if (p == nullptr) {
std::cerr << "Memory allocation failed!" << std::endl;
return 1;
}
// 手动初始化
p->x = 10;
p->y = 3.14f;
std::cout << "x = " << p->x << ", y = " << p->y << std::endl;
// free 释放内存
free(p);
return 0;
}
2. new/delete 示例
cpp
复制代码
#include <iostream>
struct MyStruct {
int x;
float y;
// 构造函数
MyStruct(int a, float b) : x(a), y(b) {
std::cout << "Constructor called!" << std::endl;
}
// 析构函数
~MyStruct() {
std::cout << "Destructor called!" << std::endl;
}
};
int main() {
// new 分配并调用构造函数
MyStruct* p = new MyStruct(10, 3.14f);
std::cout << "x = " << p->x << ", y = " << p->y << std::endl;
// delete 调用析构函数并释放
delete p;
return 0;
}
3. new/delete[](数组版本)
cpp
复制代码
#include <iostream>
int main() {
// 分配一个数组
int* arr = new int[5];
for (int i = 0; i < 5; ++i)
arr[i] = i * 10;
for (int i = 0; i < 5; ++i)
std::cout << arr[i] << " ";
std::cout << std::endl;
// 必须使用 delete[] !!!
delete[] arr;
return 0;
}
四、注意事项总结(超级重要)
| 项目 |
说明 |
| 1 |
new 和 delete 要成对使用 |
| 2 |
new[] 和 delete[] 要成对使用 (不是 delete!!!) |
| 3 |
不要混用 malloc 和 delete,或 new 和 free (严重错误!) |
| 4 |
避免内存泄漏:申请的内存必须释放,否则内存泄漏 |
| 5 |
申请后立即检查返回值 :malloc 返回 NULL,new 可以捕捉异常 |
| 6 |
构造/析构问题 :malloc 不负责对象构造,new 是 |
| 7 |
自定义 new/delete :可以通过重载 operator new / operator delete 控制内存分配策略(如内存池优化) |
| 8 |
异常安全 :尽量使用智能指针(如 std::unique_ptr、std::shared_ptr)避免手动管理内存错误 |
五、常见错误示例
cpp
复制代码
// 错误示例1:malloc分配,用delete释放
int* p = (int*)malloc(sizeof(int));
delete p; // ❌ 错,应使用 free(p);
// 错误示例2:new分配,用free释放
int* q = new int(5);
free(q); // ❌ 错,应使用 delete q;
// 错误示例3:new[]配delete
int* arr = new int[10];
delete arr; // ❌ 错,应使用 delete[] arr;
小结
malloc/free |
new/delete |
| 只分配/释放内存,不调用构造析构函数 |
分配内存并调用构造/析构函数 |
返回 void* |
返回对应类型的指针 |
| C 风格 |
C++ 风格 |
| 适合简单内存申请(不需要对象管理) |
适合对象创建与销毁(有构造析构过程) |