在C++代码中,内存泄漏的本质是new和delete没有配对调用。
第一种情况:调用了new,但是忘了调用delete
#include <iostream>
using namespace std;
class Test
{
private:
public:
Test()
{
}
~Test()
{
cout<<"清理内存"<<endl;
system("pause");
}
};
int main()
{
Test* a = new Test();
//...
system("pause");
return 0;
}
代码量比较小时,可以直观的发现和避免;代码量比较大时,还是会犯这种错误。
第二种情况:调用了new,也调用了delete,但是业务逻辑导致delete被忽略
#include <iostream>
using namespace std;
int main()
{
int* data = new int(10);
//...
FILE* fp = fopen("1.txt","r+");
if(fp == NULL)
{
cout<<"打开文件失败"<<endl;
system("pause");
return 1;
}
else
{
fwrite(&data, sizeof(int), 1, fp);
}
delete data;
data = NULL;
return 0;
}
如果1.txt文件不存在,程序直接返回,a没有得到及时释放。这种情况比较复杂,必须得根据代码业务逻辑分析进行解决。
下面介绍一种比较完美的解决方案:
1、针对有new忘了delete的情况,使用智能指针解决。
2、针对既有new也有delete,但是delete可能会被忽略的情况,使用RAII解决。
经过改良的代码如下:
#include <iostream>
using namespace std;
class Test
{
private:
int* data;
public:
Test()
{
data = new int(10);
}
~Test()
{
delete data;
data = NULL;
cout<<"清理内存"<<endl;
system("pause");
}
int getData()
{
return *data;
}
};
int main()
{
auto_ptr<Test>a(new Test());
//...
FILE* fp = fopen("1.txt","r+");
if(fp == NULL)
{
cout<<"打开文件失败"<<endl;
system("pause");
return 1;
}
else
{
int data = a->getData();
fwrite(&data, sizeof(int), 1, fp);
}
system("pause");
return 0;
}
智能指针:https://zh.wikipedia.org/wiki/%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88
RAII:https://zh.wikipedia.org/wiki/RAII