二维指针数组是int*类型,本质为“指向指针的指针”,需两步分配:先new int[rows]分配行指针数组,再对每行执行arr[i] = new int[cols];内存不连续,释放须逐行delete[]后delete[]指针数组。

什么是二维指针数组?先别急着 new
“二维指针数组”不是语法糖,而是 int** 这类类型的实际用法——它本质是「指向指针的指针」,不是连续内存块,也不等价于 int[3][4]。很多人一上来就写 int** arr = new int*[3];,却忘了后续每行还要单独分配,漏掉这步就会访问非法内存。
手动分配:两步缺一不可
要让 int** 真正可用,必须分两层分配:
- 第一层:分配指针数组本身,比如
int** arr = new int*[rows]; - 第二层:对每个
arr[i]单独分配整数数组,如arr[i] = new int[cols];
示例(3 行 4 列):
int** arr = new int*[3]; for (int i = 0; i <h3>为什么不用 vector<vector>> 替代?</vector> </h3><p>直接用 <code>std::vector<:vector>></:vector></code> 更安全,但要注意:它不是二维连续内存,每行 <code>vector</code> 是独立堆分配;若需要 C 风格接口(如传给 <code>void func(int**, int, int)</code>),它无法直接转换。此时必须用原始 <code>int**</code>,且调用方需明确知道内存布局和所有权归属。</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a> <p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p> </div> <a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div><p>常见坑:</p>
-
vector的data()只返回首行首地址,&vec[0][0]不等于int** - 把
vector<vector>>.data()</vector>强转成int**会崩溃 - 函数接收
int**时,通常还要求额外传入行列尺寸,因为指针本身不带维度信息
避免野指针和泄漏的关键点
原始二维指针极易出错,核心风险不在分配,而在释放和异常路径:
- 任何一次
new失败(比如某行new int[cols]抛std::bad_alloc),前面已分配的内存必须手动回滚释放 - 不要混合使用
new和malloc,或delete[]与delete - 如果类里管理
int**,务必显式定义析构函数、拷贝构造函数和赋值运算符(或禁用)——否则浅拷贝会导致双重释放
真正要用,建议封装成 RAII 类,或者直接上 std::unique_ptr<int>[]</int> + std::unique_ptr<int></int> 组合,但复杂度立刻上升。
实际项目里,除非对接旧 C API 或做底层内存控制,否则优先选 std::vector<:vector>></:vector> 或一维展平 + 索引计算(data[i * cols + j]),更稳。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










