几个内存泄漏的例子
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
几个内存泄漏的例子
✧new和delete要成对使用
✧new和delete要匹配
经常看到一些C++方面的书籍中这样提及到内存泄漏问题,这样的说法的意思是比较明白,但对于初学C++程序员还是很难掌握,所以下面举几个反面的例子,希望对大家有帮助。
例一:错误处理流程中的return导致的内存泄漏
bool MyFun()
{
CMyObject* pObj = NULL;
pObj = new CMyObject();
…
if (…)
return false;
…
if(…)
return false;
…
if (pObj != NULL)
delete pObj;
return true;
}
注意:红色字体部分的return之前没有释放pObj,导致内存泄漏。
例二:exception改变了程序的正常流程,导致内存泄漏
情况1:
HRESULT MyFun()
{
HRESULT hr = S_OK;
try
{
CMyObject* pObj = NULL;
pObj = new CMyObject();
…
if (…)
{
hr = E_FAIL;
throw hr;
}
…
if(…)
{
hr = E_FAIL;
throw hr;
}
…
if (pObj != NULL)
delete pObj;
}
catch (HRESULT& eHr)
{
}
return hr;
}
情况2:
void OtherFun() // 可能是自己写的其他函数;
// 也可能是其他人写的函数;
// 也可能是系统的API;
{
…
if(…)
throw exception;
…
}
bool MyFun()
{
CMyObject* pObj = NULL;
pObj = new CMyObject();
…
OtherFun();
…
if (pObj != NULL)
delete pObj;
return true;
}
注意:上面的两种情况中的throw行为将导致程序的正常流程,一旦有throw的动作发生,pObj对象将不会被正确释放(delete)。
例三:忘记释放系统API创建的资源,导致内存泄露
bool CMyClass::MyFun()
{
HANDLE hHandle = CreateEvent(NULL,FALSE,TRUE,NULL);
…
if (…)
return false;
…
return true;
}
注意:系统API CreateEvent创建的HANDLE对象,需要自己释放,否则会导致内存泄漏。还有其他一些系统的API也是如此,如:CreateFile、CreateFileMapping 等等,所以我们在使用不熟悉的系统API时,一定要仔细阅读MSDN。
例四:PostMessage可能导致的内存泄漏
// 自定义的消息结构体
typedef struct tagMSG
{
int i;
float f;
}MSG;
// 发送消息的函数
void MyFun()
{
MSG* pMsg = new MSG;
…
PostMessage(m_hWnd, WM_MYEVENT, (WPARAM)pMsg, 0);
}
// 接收消息的函数
afx_msg void OnMessage(WPARAM wParam, LPARAM lParam)
{
MSG* pMsg = (MSG*)wParam;
m_i = pMsg->i;
m_f = pMsg->f;
}
注意:OnMessage函数中忘记释放pMsg,导致内存泄漏。
例五:函数返回new的对象而导致的内存泄漏
char* MyFun()
{
char* p = new char[10];
…
return p;
}
注意:调用MyFun程序的人可能不会注意到MyFun函数内部new出的对象,往往会忽略对象p的释放。
例六:不好的类结构也会导致内存泄漏
// MyClass.h文件
class MyClass
{
public:
MyClass();
virtual ~MyClass();
BOOL Init();
BOOL UnInit();
private:
char* m_pStr;
}
// MyClass.cpp文件MyClass::MyClass()
: m_pStr(NULL)
{
}
MyClass::~MyClass()
{
}
BOOL MyClass::Init()
{
m_pStr = new char[100];
…
if (…)
{
delete m_pStr;
m_pStr = NULL;
return FALSE;
}
return TRUE;
}
BOOL MyClass::UnInit()
{
if (m_pStr != NULL)
{
delete m_pStr;
m_pStr = NULL;
}
return TRUE;
}