new和delete是C++原生操作符,负责分配+构造、析构+释放;单个对象用new/delete,数组用new[]/delete[],配错导致未定义行为;new失败抛std::bad_alloc异常。

new 和 delete 是 C++ 原生内存管理操作符,不是函数
它们直接调用全局 operator new 和 operator delete(底层通常封装了 malloc/free),但语义更明确:new 负责「分配 + 构造」,delete 负责「析构 + 释放」。写成 new int 不等于 malloc(sizeof(int)) —— 如果类型是类,new 会自动调用构造函数,delete 会自动调用析构函数。
申请单个对象或数组,语法和行为完全不同
用错括号会导致未定义行为,且编译器通常不报错:
-
int* p = new int(42);→ 分配一个int,初始化为42;对应必须用delete p; -
int* arr = new int[10];→ 分配 10 个未初始化的int;对应必须用delete[] arr; -
delete arr;(对数组)或delete[] p;(对单个对象)→ 行为未定义,常见表现为程序崩溃、内存泄漏或静默损坏 - 数组 new 不支持带初值列表(如
new int[5]{1,2,3}在 C++11 后合法,但delete[]仍必须配对)
new 可能抛出异常,需考虑失败处理
默认 new 在内存不足时抛出 std::bad_alloc,而不是返回 nullptr:
try {
int* p = new int[1000000];
} catch (const std::bad_alloc& e) {
// 处理分配失败
std::cerr << "Allocation failed: " << e.what() << '\n';
}若想让 new 返回 nullptr 而非抛异常,用 nothrow 版本:
立即学习“C++免费学习笔记(深入)”;
-
int* p = new (std::nothrow) int[1000];→ 分配失败时返回nullptr,不会抛异常 - 此时必须显式判空:
if (!p) { /* handle error */ } - 仍需用
delete[] p;(若为数组),即使p是nullptr,delete和delete[]对空指针是安全的
与智能指针配合使用才是现代 C++ 的正确姿势
裸 new/delete 容易漏掉 delete、重复 delete 或配对错误。除非写底层容器或性能关键路径,否则应优先用 std::unique_ptr 或 std::shared_ptr:
auto p = std::make_unique(42); // 自动管理单个对象 auto arr = std::make_unique (100); // 自动管理数组(C++14 起) // 无需手动 delete,离开作用域自动释放
真正需要手写 new/delete 的场景极少,比如实现自定义分配器、封装 C API 返回的裸指针,或调试内存问题时观察原始行为。
最容易被忽略的是:数组 delete 必须带 [],且这个规则无法靠编译器强制检查;一旦写错,问题往往延迟暴露,调试成本极高。











