C++中正确删除二级指针(指向指针的指针)的方法
二级指针内存释放的问题分析
问题场景
场景1:执行delete poinerToBufferPointer时程序崩溃
char* buffer = new char[8]; memset(buffer, 1, 8); char** poinerToBufferPointer = &buffer; delete poinerToBufferPointer; delete[] buffer;
场景2:注释掉delete poinerToBufferPointer后程序正常运行
char* buffer = new char[8]; memset(buffer, 1, 8); char** poinerToBufferPointer = &buffer; //delete poinerToBufferPointer; delete[] buffer;
场景3:删除解引用后的指针,后续delete[] buffer失败
char* buffer = new char[8]; memset(buffer, 1, 8); char** poinerToBufferPointer = &buffer; delete *poinerToBufferPointer; // <--- 仅删除指向的指针 delete[] buffer;
核心疑问
- 谁来负责删除这个二级指针?
- 这些操作背后的内存变化是怎样的?
- 正确删除相关指针的方法是什么?
内存变化与问题解析
首先明确内存分配的本质:
new char[8]:在堆内存上分配了8字节的连续空间,buffer是栈内存上的指针变量,存储的是这块堆空间的地址。char** poinerToBufferPointer = &buffer:poinerToBufferPointer同样是栈内存上的指针变量,存储的是栈上buffer变量的地址。
逐个分析错误操作:
delete poinerToBufferPointer崩溃的原因:delete仅用于释放堆上通过new分配的内存,但poinerToBufferPointer指向的是栈上的buffer变量。栈内存由系统自动管理,不能用delete手动释放,强行调用会直接触发内存访问错误,导致程序崩溃。删除
*poinerToBufferPointer后delete[] buffer失败的原因:*poinerToBufferPointer等价于buffer,也就是堆上8字节数组的地址。这里用delete(而非数组对应的delete[])释放数组本身就不符合规则,更关键的是,这已经把堆内存释放了,后续再执行delete[] buffer属于重复释放同一块内存,同样会触发内存错误。二级指针的删除责任:
poinerToBufferPointer是栈上的局部变量,当它所在的作用域结束(比如函数执行完毕返回),系统会自动回收它占用的栈内存,完全不需要手动delete。只有当二级指针本身是通过new在堆上分配的(比如char** ptr = new char*;),才需要用delete释放它。
正确操作方式
只需要释放堆上分配的数组内存即可,栈上的指针变量(包括buffer和poinerToBufferPointer)不需要手动处理:
char* buffer = new char[8]; memset(buffer, 1, 8); char** poinerToBufferPointer = &buffer; // 仅释放堆上的数组内存 delete[] buffer;
如果是堆上分配的二级指针(比如动态创建指针数组),则需要逐层释放:
// 示例:堆上的二级指针 char** ptrArray = new char*[2]; ptrArray[0] = new char[8]; ptrArray[1] = new char[8]; // 先释放每个一级指针指向的数组 delete[] ptrArray[0]; delete[] ptrArray[1]; // 再释放二级指针本身 delete[] ptrArray;
内容的提问来源于stack exchange,提问作者user63898
相关产品推荐
相关产品推荐

