指针重复释放是C++开发中的常见问题,本文通过实例分析原因并提供两种解决方案。
观察以下代码片段,虽然对pPointer进行了多次释放操作,并在第二次释放前做了判空处理,但程序仍然出现了重复释放错误。

#include
using namespace std;
void release(int *pPointer){
delete pPointer;
pPointer = nullptr;
}
int main() {
int *pPointer = new int();
release(pPointer);
if(pPointer) delete pPointer;
return 0;
}
运行结果显示了双重释放错误,尽管代码中包含了判空检查,问题依然存在。
free(): double free detected in tcache 2 Process finished with exit code 134
通过地址打印实验可以证明,函数参数传递过程中指针发生了拷贝。main函数和release函数中的pPointer实际上是不同的指针变量,只是指向相同的内存地址。
void release(int *pPointer){
printf("release pPointer:%xn",&pPointer);
delete pPointer;
pPointer = nullptr;
}
int main() {
int *pPointer = new int();
printf("main pPointer:%xn",&pPointer);
release(pPointer);
if(pPointer)delete pPointer;
return 0;
}
执行结果清楚显示了两个指针变量的地址差异。
main pPointer:f22d1fb0 release pPointer:f22d1f98 free(): double free detected in tcache 2 Process finished with exit code 134
问题产生的具体过程可以分为三个步骤:
修改release函数参数为指针引用,确保操作的是同一个指针变量。
void release(int *& pPointer){
delete pPointer;
pPointer = nullptr;
}
该方法解决了问题,验证结果显示两个函数中的指针地址相同。
main pPointer:c12d0580 release pPointer:c12d0580 Process finished with exit code 0
通过二级指针参数也能有效解决问题,需要注意解引用操作。
void release(int **pPointer){
printf("release pPointer:%xn",pPointer);
delete *pPointer;
*pPointer = nullptr;
}
int main() {
int *pPointer = new int();
printf("main pPointer:%xn",&pPointer);
release(&pPointer);
if(pPointer)delete pPointer;
return 0;
}
执行结果验证了方案的有效性。
main pPointer:d2699950
release pPointer:d2699950
Process finished with exit code 0
通过分析指针传递机制和提供两种解决方案,本文完整阐述了避免重复释放内存的有效方法。