最稳妥的方式是先分配一块连续内存作为数据存储,再分配指针数组模拟二维结构;需先 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 // 使用后释放:
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 次小内存分配,性能差。
使用 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 <h3>常见错误:只 delete[] 一层就认为释放完成</h3> <p>这是最常踩的坑——以为 <code>delete[] arr</code> 就释放了全部内存,实际只是释放了行指针数组,底层数据还在泄漏。</p> <ul> <li>错误写法:<code>delete[] arr;</code>(漏掉 <code>data</code>)</li> <li>错误写法:<code>delete[] arr[0];</code>(漏掉 <code>arr</code>,导致行指针数组泄漏)</li> <li>更隐蔽的问题:在构造中途抛异常,没走到释放逻辑——所以优先用 RAII 容器</li> </ul> <p>连续内存方案里,两层释放缺一不可;而 <code>std::vector</code> 或 <code>unique_ptr</code> 能天然规避这类问题。</p> <p>真正麻烦的不是分配,而是确保每块内存都有且仅有一次对应的释放点,尤其在函数提前返回或异常发生时。</p></int></int>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











