本质是「一维连续内存」;new int[rowscols]分配物理连续内存,通过icols+j索引模拟二维,性能高且释放简单;而new int*[rows]配合循环new int[cols]导致内存不连续、易泄漏、释放复杂。

用 new 分配二维数组,本质是「指针的指针」还是「一维连续内存」?
直接结论:C++ 没有原生二维数组动态分配语法,new int[rows][cols] 仅在 cols 是编译期常量时合法;实际项目中几乎总得手动管理。关键区别在于——你想要「逻辑二维、物理连续」(推荐),还是「每行独立分配、可变长」(灵活但开销大)。
new int*[rows] + 循环 new int[cols] 的坑在哪?
这是最常写的写法,但极易内存泄漏和释放错误:
- 必须用
delete[]逐行释放,漏一行就泄漏;最后还得delete[]行指针数组本身 - 每行内存不连续,缓存不友好,访问速度慢
- 如果某次
new int[cols]失败,前面已分配的行必须手动回滚释放(否则泄漏) - 不能直接传给期望
int (*)[N]的函数(类型不匹配)
示例错误释放:delete[] arr;(只释放了指针数组,没释放每行数据)
更安全的做法:用 new int[rows * cols] + 手动索引计算
物理上是一维连续内存,逻辑上模拟二维,兼顾性能与可控性:
- 分配:
int* data = new int[rows * cols]; - 访问第
i行第j列:data[i * cols + j] - 释放只需一次:
delete[] data; - 可直接传递给接受
int*和行列参数的函数 - 若需类似
arr[i][j]语法,可用二级指针包装(但别忘了这层指针本身也要管理):
int** arr = new int*[rows]; for (int i = 0; i <h3>现代 C++ 应该用什么替代 <code>new</code>?</h3><p>裸 <code>new</code>/<code>delete</code> 在 C++11 后基本属于遗留写法。真正该考虑的是:</p>
-
std::vector<:vector>></:vector>:适合行长度不等、生命周期明确的场景;但内存不连续 -
std::vector<int></int>+ 手动索引(同上一节):推荐用于固定尺寸、高性能需求,如图像处理、矩阵运算 -
std::unique_ptr<int></int>包裹一维内存,或std::unique_ptr<int></int>包裹指针数组:能自动释放,但后者仍需循环初始化
手写 new 分配二维数组的代码,在真实项目里大概率会被 Code Review 打回——不是因为它错,而是它绕过了 RAII,把资源管理责任推给了人。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











