C++中new/delete用于手动堆内存管理,new分配并构造对象,delete析构并释放;必须严格配对使用(new对应delete、new[]对应delete[]),否则导致未定义行为;现代C++推荐优先使用智能指针和标准容器替代。

在C++中,new和delete是手动管理堆内存的核心操作符。它们不自动初始化对象、不调用智能指针机制,需要程序员明确配对使用,否则极易引发内存泄漏、重复释放或悬空指针等问题。
new:在堆上分配内存并构造对象
new完成两件事:申请足够大小的未初始化内存,并调用对应类型的构造函数完成初始化。它返回指向该对象的指针,类型与所创建对象严格匹配。
- 分配单个对象:
int* p = new int(42);—— 分配一个int,初始化为42 - 分配对象(带构造):
std::string* s = new std::string("hello");—— 调用string构造函数 - 分配数组:
double* arr = new double[10];—— 分配10个未初始化double(注意:不支持带参数的数组初始化) - 失败时抛出
std::bad_alloc异常(除非用new(std::nothrow)返回nullptr)
delete:析构对象并释放内存
delete也做两件事:先调用对象的析构函数(如果类型有析构函数),再把内存归还给堆。必须与new严格匹配使用,否则行为未定义。
- 释放单个对象:
delete p;—— 先调用~int()(无操作),再释放内存 - 释放对象:
delete s;—— 先调用string::~string(),再释放 - 释放数组必须用
delete[]:delete[] arr;—— 否则只析构第一个元素,且释放逻辑错误 - 对空指针执行
delete是安全的(无操作),但对已释放过的指针再次delete是严重错误
常见陷阱与关键规则
动态内存管理出错往往不是语法问题,而是逻辑疏忽。以下四条必须牢记:
立即学习“C++免费学习笔记(深入)”;
-
new 和 delete 必须成对出现:用
new分配,就用delete;用new[]分配,就用delete[]——混用导致未定义行为 -
不要对栈对象或字面量使用 delete:
int x; delete &x;或delete "abc";都会崩溃 -
释放后立即置空指针:
delete p; p = nullptr;可避免二次释放,但不能解决所有悬空指针问题 -
避免裸指针跨作用域传递所有权:谁分配、谁释放应清晰;复杂场景优先用
std::unique_ptr或std::shared_ptr
替代方案:为什么现代C++更推荐智能指针
手动管理new/delete容易出错,而std::unique_ptr和std::shared_ptr能自动绑定生命周期:
-
auto p = std::make_unique—— 出作用域自动(42); delete -
auto arr = std::make_unique—— 自动用(10); delete[] -
std::shared_ptr支持多所有者共享,引用计数归零时自动清理 - 这些智能指针底层仍调用
new/delete,但把“何时释放”的决策从人脑转移到了RAII机制
掌握new和delete是理解C++内存模型的基础,但在实际项目中,应尽量用标准容器(std::vector、std::string)和智能指针替代裸动态分配。只有在性能敏感、需精细控制或封装底层资源时,才直接使用它们。









