内存泄露的可能引起原因


例如:定义一个成员变量  

     CWinThread   *m_pWinThread;  

如果没有在程序末尾删除这个指针,delete m_pWinThread; 则会出现

Detected Memory leaks! 的错误。

 

2. 线程需要关闭 TerminateThread

 

3. Socket so对象需要被关闭 closesocket(so)

 

否则会出现内存泄漏错误。

///

  CWinThread   *m_pWinThread;  

   

  启动线程时  

  m_pWinThread=AfxBeginThread(TestServ,(LPVOID)this);  

   

  退出应用程序使用(可以把着段代码写在窗口销毁的函数DestroyWindow()中)  

  void   CThreadtestDlg::OnOK()    

  {  

  if(m_pWinThread!=NULL){  

  if(m_pWinThread->m_hThread!=NULL){  

  DWORD   dwExitCode=0;  

  GetExitCodeThread(m_pWinThread->m_hThread,&dwExitCode);  

  if(dwExitCode==STILL_ACTIVE){  

  TerminateThread(m_pWinThread->m_hThread,0);  

  }  

  delete   m_pWinThread;  

  }  

  }  

  CDialog::OnOK();  

  }  

 //

大家经常听到一个名词叫内存泄漏。到底怎样才会遇到内存泄漏,内存泄漏到底该怎么定位,大家却都很糊涂。实际上我对这个问题也很头疼,下面就是我关于这个问题的一些小看法:

1. 什么叫内存泄漏?
内存泄漏是指你分配了内存,使用完毕后没有正确释放它。这样这个内存就不能再被使用。

例如:
void test()
{
    char * p = new char[MAX_PATH];
    GetModuleFileName(NULL,p, MAX_PATH);
    strcat(p+strlen(p) - 3, "txt");
    CStdioFile file(p);
    file.WriteString("text");
    file.Close();
}

注意:上面的指针p函数退出后就无法再释放,new char[MAX_PATH]分配的内存就泄漏了。

2. 何时我的程序泄漏了?
从外部看,我们很难100%准确的方法去判断是否有内存泄漏。实际上,一块内存是否被泄漏,从外部看只有当进程结束才能知道。因为你完全可以从开始分配一块内存,直到结束才去释放它。

基本上,下面行为不能说明内存泄漏:
a) 任务管理器上显示内存使用增加了1MB
b) 内存使用很多(我见过最大内存使用超过1.5GB的程序)

下面行为可能意味着有内存泄漏:
a) 一个进程的内存使用量按照一个固定的速度稳定的增长(例如每小时增加20MB)

如果可以在VC IDE中运行程序,当程序退出时,系统会报一堆泄漏错误。

3. 如何定位
从编译器角度讲,在分配内存后,任何时候释放都是合适的,因此系统不会知道你何时适合去释放内存。在进程运行过程中,你只能估计是否有内存泄漏,而不能确定一定有内存泄漏。一般来说,我们可以用以下一些办法定位:

a) 使用性能监视器跟踪进程的内存使用情况,如果它在不断增长,且增长速度趋于稳定,一般说明在某个循环性的操作中有内存泄漏
b) 在编译器中按照Debug模式运行程序,运行一定时间后(例如2天),使用正常的方式停止进程
正常情况下,你不会收到任何和内存有关的异常。如果你程序有内存泄漏,你会收到如下错误信息:

Detected memory leaks!
Dumping objects ->
D:\projects\EnumWnd\EnumWndDlg.cpp(185) : {78} normal block at 0x00421330, 100 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.

注意,这里EnumWndDlg.cpp(185)应该是分配这块内存的地方。这是因为没有所谓的内存泄漏点,只有在某点分配的内存被泄漏了。

4. 如何分析内存泄漏
内存泄漏分析一般是通过分析内存生命周期来进行的。你必须对你的内存的可能使用情况有所了解。在此基础上,你应该了解在那个地方内存应该被释放。如果有内存泄漏,说明程序没有走到那个地方,或者释放代码没有正确执行。因此你可能需要跟踪你代码的执行情况,通过分析为什么代码没有按照预期走到内存释放处,了解为什么内存泄漏了。

常见的原因:

a) 忘记释放
b) 释放的方法错误
例如:把指针加入诸如CArray之类的集合对象中,释放时应该首先通过delete操作删除指针指向的对象,然后才能去调用诸如RemoveAll函数去释放集合中的指针。单纯析构诸如CArray之类的对象,不会自动释放它所包含的指针所指向的对象。

c) 析构函数错误:如果你对象中包含指针,那么你析构函数需要正确的释放这些指针。如果你析构函数不做这些,就会有内存泄漏
d) 线程问题:如果线程被你通过TerminateThread中止,那么它所分配的对象一般不会有机会被释放。这是那些喜欢在线程外中止线程的人经常遇到的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值