最稳妥的方式是先分配一块连续内存作为数据存储,再分配指针数组模拟二维结构;需先 delete[] 行指针数组,再 delete[] 底层数据数组。

用 new 分配连续内存的二维数组
最稳妥的方式是分配一块连续内存,再用指针算术模拟二维结构。这样避免指针数组的多次堆分配,也方便释放。
- 先
new一个一维数组:大小为rows * cols - 再
new一个int*数组,每个元素指向第i行起始位置:即data + i * cols - 释放时必须先
delete[]行指针数组,再delete[]底层数据数组
示例:
int** create2DArray(int rows, int cols) {
int* data = new int[rows * cols];
int** arr = new int*[rows];
for (int i = 0; i < rows; ++i) {
arr[i] = data + i * cols;
}
return arr;
}
<p>// 使用后释放:
delete[] arr[0]; // 即 data
delete[] arr;std::vector> 是更安全的选择
手动管理 new/delete 容易漏掉某一层释放,尤其在异常路径下。用 std::vector 能自动处理内存,且支持移动语义。
-
std::vector<:vector>></:vector>每行独立分配,内存不连续,但写法直观、异常安全 - 如果需要连续内存,可用单个
std::vector<int></int>+ 手动索引:vec[i * cols + j] - 构造时可预分配容量:
vec.reserve(rows)避免多次扩容
注意:不要用 vector<vector>> v(rows, vector<int>(cols))</int></vector> 初始化大量小行——它会触发 rows 次小内存分配,性能差。
立即学习“C++免费学习笔记(深入)”;
使用 std::unique_ptr 管理裸指针二维数组
若必须用原始指针(比如对接 C API 或追求极致控制),std::unique_ptr 可避免手动 delete 错误。
- 用
std::unique_ptr<int></int>管理底层数据 - 用
std::unique_ptr<int></int>管理行指针数组(C++14 起支持) - 无法直接用
unique_ptr<int></int>—— C++ 不支持未知边界的二维数组类型
示例:
auto data = std::make_unique<int[]>(rows * cols);
auto arr = std::make_unique<int*[]>(rows);
for (int i = 0; i < rows; ++i) {
arr[i] = data.get() + i * cols;
}常见错误:只 delete[] 一层就认为释放完成
这是最常踩的坑——以为 delete[] arr 就释放了全部内存,实际只是释放了行指针数组,底层数据还在泄漏。
- 错误写法:
delete[] arr;(漏掉data) - 错误写法:
delete[] arr[0];(漏掉arr,导致行指针数组泄漏) - 更隐蔽的问题:在构造中途抛异常,没走到释放逻辑——所以优先用 RAII 容器
连续内存方案里,两层释放缺一不可;而 std::vector 或 unique_ptr 能天然规避这类问题。
真正麻烦的不是分配,而是确保每块内存都有且仅有一次对应的释放点,尤其在函数提前返回或异常发生时。


















