必须用delete[]逐层释放:先循环delete[]每行内存,再delete[]首指针数组;只delete[]首指针会导致每行内存泄漏。

new申请的二维数组怎么delete
必须用delete[]逐层释放,不能只对首指针delete[] p就完事——那只会释放第一维指针数组,每行实际分配的内存全泄露了。
典型错误写法:int** p = new int*[rows]; for(int i=0; i<rows p new int ... delete> → 后续访问<code>p[0]会崩溃,因为p[0]指向的堆内存没被释放,且指针值已失效。
- 先循环
delete[] p[i]释放每一行的int[cols]内存 - 再
delete[] p释放存放行指针的int*[rows]数组 - 释放后建议置空:例如
p[i] = nullptr;和p = nullptr;,避免野指针误用
vector>不用手动释放,但要注意拷贝开销
如果只是需要二维逻辑结构,std::vector<:vector>></:vector>是更安全的选择——析构时自动清理所有内存,无需delete操作。
但要注意:它不是连续内存布局,每行vector独立分配;频繁插入/删除某一行时可能触发多次重分配;深拷贝(如传值参数)会产生完整副本,性能敏感场景要改用std::vector<int></int>加索引计算模拟二维。
- 初始化:
std::vector<:vector>> mat(rows, std::vector<int>(cols));</int></:vector> - 访问仍用
mat[i][j],语法一致 - 若需连续内存,改用
std::vector<int> data(rows * cols);</int>,访问写成data[i * cols + j]
malloc + free怎么配对释放二维数组
用malloc申请二维数组通常有两种方式:一种是分两步(类似new),另一种是单次分配大块内存+偏移计算。释放方式必须严格对应申请方式。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
常见错误:用free(p)释放分步申请的int**首指针,漏掉各行free(p[i]);或对单次分配的大块内存误调多次free。
- 分步申请(不推荐):
int** p = (int**)malloc(rows * sizeof(int*)); for(...) p[i] = (int*)malloc(cols * sizeof(int));→ 释放顺序:先循环free(p[i]),再free(p) - 单次分配(推荐):
int* data = (int*)malloc(rows * cols * sizeof(int)); int** p = (int**)malloc(rows * sizeof(int*)); for(...) p[i] = data + i * cols;→ 只需free(p); free(data);
RAII封装能彻底避免释放遗漏
手动new/delete容易漏、错序、重复释放。真正健壮的做法是把二维数组封装进类,构造时申请,析构时自动释放。
哪怕只是临时项目,也值得花几分钟写个轻量包装。重点在于:析构函数里释放逻辑必须和构造函数中申请路径完全镜像;移动语义(C++11+)可避免不必要的拷贝。
- 核心字段通常是
int* data_;和int** rows_;(或仅std::unique_ptr<int></int>+ 索引) - 禁止用户直接访问裸指针,提供
at(i,j)或operator()做边界检查 - 若使用
std::unique_ptr管理int*,则无需手写析构函数
越复杂的释放逻辑,越容易在异常路径下出问题。别依赖“我肯定记得释放”,让编译器和RAII替你记。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










