必须用 delete[] 与 new[] 配对,否则行为未定义;new[] 返回 t* 不含长度信息,需手动管理大小;推荐优先使用 std::vector 替代裸 new[]/delete[]。

用 new[] 分配,但必须配对使用 delete[]
堆上分配数组最直接的方式是 new[],它返回指向首元素的指针。关键在于:**new[] 和 delete[] 必须严格配对**,否则行为未定义——常见表现是程序崩溃、内存泄漏或静默损坏。
例如分配 10 个 int:
int* arr = new int[10]; // ✅ 正确:用 new[] // ... 使用 arr[0] 到 arr[9] delete[] arr; // ✅ 必须用 delete[],不是 delete
如果误写成 delete arr;,编译器不会报错,但运行时可能跳过析构(对类类型)或破坏堆元数据。
为什么不用 new T[n] 返回 T* 而不是 T[]
C++ 中数组类型(如 int[10])是不可直接返回或赋值的,new[] 实际返回的是指向首元素的指针(T*),不携带长度信息。这意味着:
- 你得自己记住数组大小,
delete[]才能正确释放 - 无法通过
sizeof(arr)获取长度——结果是sizeof(T*),通常为 4 或 8 字节 - 传参给函数时,本质上传的是裸指针,调用方无从得知原长度
更安全的替代方案:优先用 std::vector
手动管理 new[]/delete[] 容易出错,尤其在异常路径或提前 return 时。现代 C++ 推荐用 std::vector:
std::vector<int> arr(10); // 自动在堆上分配,大小可查 arr.size(); // ✅ 返回 10 // 异常安全:析构自动释放内存 // 支持 push_back、resize、迭代器等</int>
例外情况才考虑裸 new[]:比如需要与 C API 交互、做底层内存池、或极端性能场景下避免 vector 的少量额外开销(如容量冗余、size 成员)。
注意 new[] 初始化的语法细节
默认初始化(值为不确定)和零初始化有明确区别:
-
new int[5]→ 元素值未定义(栈上变量同理) -
new int[5]{}或new int[5]()→ 所有元素零初始化(int变 0,double变 0.0) -
new std::string[3]→ 调用每个std::string的默认构造函数(空字符串)
对自定义类型,new[] T[n] 会调用 n 次默认构造;delete[] 则调用 n 次析构——这是它必须知道长度的根本原因。
真正难的不是怎么写 new[],而是确保每条执行路径都走到对应的 delete[],且没重复释放、没遗漏释放。稍复杂点的逻辑里,这比看起来危险得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











