
new 和 delete 详解在C++中,new 和 delete 是用于动态内存分配和释放的运算符。它们允许程序在运行时管理堆内存,是实现动态数据结构(如链表、树)和灵活资源管理的基础。
new 运算符分配单个对象:
Type* ptr = new Type; // 默认初始化(内置类型值未定义)
Type* ptr = new Type(value); // 直接初始化
Type* ptr = new Type{value}; // 列表初始化(C++11起)分配数组:
Type* arr = new Type[size]; // 分配包含size个元素的数组值初始化:
Type* ptr = new Type(); // 值初始化为0或默认构造函数delete 运算符释放单个对象:
delete ptr; // 调用析构函数(如有)并释放内存释放数组:
delete[] arr; // 释放数组内存,需使用[]告知编译器释放多个对象new 的执行步骤operator new(或 operator new[] 用于数组)分配原始内存。delete 的执行步骤operator delete(或 operator delete[])释放内存。new 和 deleteoperator new 和 operator delete:
底层函数,可被重载以自定义内存分配行为。
void* operator new(size_t size); // 分配单个对象
void* operator new[](size_t size); // 分配数组
void operator delete(void* ptr); // 释放单个对象
void operator delete[](void* ptr); // 释放数组示例:
void* raw_memory = operator new(sizeof(int)); // 分配原始内存
int* ptr = static_cast<int*>(raw_memory); // 转换为int指针
*ptr = 42; // 手动赋值
operator delete(ptr); // 释放内存(不调用析构函数)new(Placement New)在已分配的内存上构造对象:
void* buffer = operator new(sizeof(MyClass)); // 分配原始内存
MyClass* obj = new (buffer) MyClass(); // 在buffer上构造对象
obj->~MyClass(); // 显式调用析构函数
operator delete(buffer); // 释放内存int* arr = new int[10]; // 分配10个int的数组
delete[] arr; // 释放数组
// 多维数组
int** matrix = new int*[5]; // 分配5行
for (int i = 0; i < 5; ++i) {
matrix[i] = new int[10]; // 每行10列
}
// 释放
for (int i = 0; i < 5; ++i) {
delete[] matrix[i];
}
delete[] matrix;int* arr = new int[5]{1, 2, 3, 4, 5}; // C++11起支持列表初始化在对数组进行动态分配时,会自动在之前多分配一块空间用来储存所要开辟的空间个数,以便将来用delete释放空间。
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:
new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申 请空间失败时会抛异常,malloc会返回NULL。
new的原理
delete的原理
new T[N]的原理
delete[]的原理
原因:忘记调用 delete 释放 new 分配的内存。
示例:
void leak() {
int* ptr = new int; // 分配内存
// 未释放内存就返回
} // 内存泄漏!原因:释放内存后仍保留指向该内存的指针。
示例:
int* ptr = new int;
delete ptr;
*ptr = 10; // 悬空指针解引用,未定义行为原因:多次释放同一块内存。
示例:
int* ptr = new int;
delete ptr;
delete ptr; // 重复释放,未定义行为delete 和 delete[]错误示例:
int* arr = new int[10];
delete arr; // 错误!应使用delete[]对于内置类型,程序会崩溃;而对于自定义类型,程序不会崩溃。
operator new 和 operator deletevoid* operator new(size_t size) {
void* p = malloc(size);
// 可添加内存分配日志、性能监控等
return p;
}
void operator delete(void* p) noexcept {
free(p);
// 可添加内存释放日志等
}class MyClass {
public:
static void* operator new(size_t size) {
// 自定义分配逻辑
return ::operator new(size);
}
static void operator delete(void* p) noexcept {
// 自定义释放逻辑
::operator delete(p);
}
};特性 | C++ new/delete | C语言 malloc/free |
|---|---|---|
类型安全 | 自动推导类型,无需强制转换 | 需要显式转换(如 (int*)malloc()) |
构造/析构函数 | 自动调用构造函数和析构函数 | 不调用构造/析构函数 |
初始化 | 支持直接初始化和列表初始化 | 仅分配内存,不初始化值 |
数组语法 | 直接使用 new Type[size] | 需要计算总大小(如 malloc(size*sizeof(Type))) |
智能指针支持 | 与标准库智能指针无缝配合 | 需手动封装为智能指针 |
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。 不同的地方是:
new/delete 是C++动态内存分配的核心机制,适用于: std::unique_ptr 和 std::shared_ptr 能有效避免内存泄漏,提高代码安全性。new 和 delete 配对使用,避免悬空指针和重复释放。