C++中,很多方式可以引起内存泄漏,譬如如下代码:
class RefClass
{
public:
RefClass(int n_)
{
pInt = new int(n_);
}
~RefClass()
{
if(NULL != pInt)
{
delete pInt;
pInt = NULL;
}
}
int* pInt = NULL;
};
/*
检查*p_n_是否为0,是的话,通过删除p_n_,间接删除ref_class_->pInt
*/
void checkPtr(RefClass* ref_class_, int*& p_n_)
{
if(*p_n_ == 0)
{
delete p_n_; //删除指向的内存
p_n_ = NULL; //置NULL
}
return;
}
void main()
{
RefClass* _pRefClass = new RefClass(0);
int* _p_n = _pRefClass->pInt;
checkPtr(_pRefClass, _p_n);
delete _pRefClass; //析构类对象,会造成内存泄漏
}
运行上述程序,会发生内存泄漏。删除内存的操作很规范
delete p_n_; //删除指向的内存
p_n_ = NULL; //置NULL
为什么还会泄漏呢? 根本原因是,调用checkPtr(RefClass* ref_class_, int*& p_n_)函数时,传入的是指向ref_class_->pInt内存的另一个指针_p_n,
delete p_n_; // 删除指向的内存,即ref_class_->pInt指向的内存被删除
p_n_ = NULL; // p_n_置NULL,但是!!!ref_class_->pInt没有被置NULL,因为指针p_n_并不是ref_class_->pInt的引用。p_n_只是main中_p_n的引用
// 此时ref_class_->pInt成为野指针,因为它指向的内存已经被delete了
正确的用法是,将_p_n声明为 _pRefClass->pInt的引用,即int*& _p_n = _pRefClass->pInt;