在 C++ 中,new 和 delete 是用于动态内存管理 的核心运算符。它们允许程序在运行时从**堆区(Heap/Free Store)**申请和释放内存,这与编译时确定大小的栈区内存不同。
以下是 new 和 delete 的详细用法、核心特性及注意事项。
1. 基本语法与步骤
使用堆区内存通常遵循以下四个步骤:
- 声明指针:定义一个指向特定类型的指针变量。
- 申请内存 :使用
new运算符向系统申请内存,并将返回的地址赋值给指针。 - 使用内存 :通过解引用指针(
*ptr)或箭头运算符(ptr->member)访问和操作内存中的数据。 - 释放内存 :当不再需要该内存时,使用
delete运算符释放它,防止内存泄漏。
1.1 单个变量的分配与释放
cpp
#include <iostream>
using namespace std;
int main() {
// 1. 声明指针
int* p = nullptr;
// 2. 申请内存 (new)
// 语法: new 数据类型(初始值);
p = new int(10); // 申请一个 int 大小的内存,并初始化为 10
// 3. 使用内存
cout << *p << endl; // 输出: 10
*p = 20; // 修改值
cout << *p << endl; // 输出: 20
// 4. 释放内存 (delete)
// 语法: delete 指针变量;
delete p;
p = nullptr; // 建议:释放后将指针置空,避免成为野指针
return 0;
}
1.2 数组的分配与释放
如果需要使用 new 分配数组,必须使用 delete[] 来释放,否则会导致未定义行为(通常表现为内存泄漏或程序崩溃)。
cpp
int main() {
// 1. 申请数组内存
// 语法: new 数据类型[元素个数];
int* arr = new int;
// 2. 使用数组
for(int i = 0; i < 5; ++i) {
arr[i] = i * 10;
}
// 3. 释放数组内存
// 注意:必须使用 delete[],而不是 delete
delete[] arr;
arr = nullptr;
return 0;
}
2. new/delete 与 malloc/free 的区别
虽然 C 语言的 malloc/free 也能进行动态内存管理,但 C++ 推荐使用 new/delete,主要区别如下:

cpp
class Student {
public:
Student(int age) : m_age(age) {
cout << "构造函数被调用" << endl;
}
~Student() {
cout << "析构函数被调用" << endl;
}
private:
int m_age;
};
int main() {
// 使用 new:自动调用构造函数
Student* s = new Student(18);
// 使用 delete:自动调用析构函数
delete s;
return 0;
}
// 输出:
// 构造函数被调用
// 析构函数被调用
3. 高级用法与注意事项
3.1 内存分配失败的处理
标准的 new 在失败时会抛出异常。如果你希望它在失败时返回 nullptr 而不是抛出异常,可以使用 nothrow 形式:
cpp
#include <new> // 需要包含此头文件
int* p = new (std::nothrow) int;
if (p == nullptr) {
cout << "内存分配失败" << endl;
} else {
// 使用内存
delete[] p;
}
3.2 常见错误与最佳实践
-
匹配使用:
new对应deletenew[]对应delete[]- 严禁混用 :用
delete释放new[]分配的数组,或用free释放new分配的内存,都会导致未定义行为。
-
避免内存泄漏:
- 确保每一个
new都有对应的delete。 - 如果在
new之后、delete之前发生了异常或提前返回,内存可能无法释放。建议使用智能指针(如std::unique_ptr或std::shared_ptr)来自动管理生命周期,这是现代 C++ 的首选方式。
- 确保每一个
-
避免野指针:
- 执行
delete p后,指针p仍然指向原来的地址(即悬空指针)。再次使用*p或delete p会导致严重错误。 - 习惯 :删除后立即将指针赋值为
nullptr(p = nullptr;)。
- 执行
-
不要重复释放:
- 对同一个指针执行两次
delete是未定义行为。如果指针已置为nullptr,再次delete nullptr是安全的(无操作)。
- 对同一个指针执行两次
4. 总结
- 简单类型 :
new int(10)->delete p - 数组类型 :
new int->delete[] p - 类对象 :
new Class()->delete p(自动调用构造/析构) - 现代 C++ 建议 :尽量使用智能指针(
std::unique_ptr,std::shared_ptr)替代裸指针的手动new/delete,以从根本上杜绝内存泄漏和悬空指针问题。