我发现我的程序有不少内存泄露,但是不知道到底是哪出的问题。 请问应该怎么样判断?请先提供解决这类问题的大体思路,最好在提供些好方法 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 cdc CDc后一定要放掉:广告:小生刚学VC不久,个人认为学好VC不难,但需要多加练习,因此本着这一思想也因个人需要做了这个小程序,此程序也是本人第一个完成的程序,绝无抄袭之处(如有雷同属巧合)或许有许多不足之处,敢请大家指教:)再且,此程序只有原设想其中一个功能,其它功能正在边学边做当中.有人说这个程序也需注册,对于这一点我不敢苟同,虽然程序简单,但我还是觉得还是有许用处的.而且对于注册功能也是我学习之一.(小生学习VC两月,自觉进步甚多,同时也想在此感谢CSDN各位的大力帮助)http://www10.brinkster.com/cttt/china 用vc debug版,在调试状态下运行,推出程序之后,如果有内存泄漏,vc的output/debug窗口会输出内存泄漏信息,并且指出泄露的内存是那个文件那一行代码分配的,分配的序号是多少,根据这些信息,可以单步跟踪到分配内存的地方。 内存泄漏都是由于动态分配引起的吧,就是在堆上分配的内存,请认真检查你动态分配的内存可曾释放??比较容易出错的是二维三维数组的动态分配。此外如果用MFC,推荐一篇文章:最近,笔者用VC++编写一个屏幕保护程序的时候,发现了内存泄露的问题,感到 非常困惑。后来,在参考几个例子的基础上,解决了这个问题。下面让我们分析 其原因和处理方法: ---- 笔者由CWnd派生了一个子类CDrawWnd, 在主程序类的InitInstance()中添加了 如下代码: m_pMainWnd=new CDrawWnd();m_pMainWnd- >Create(.....);return TRUE;---- 在调试运行通过后,VC++的调试器报告内存泄露。显然,问题只可能出在上面的 第一行代码上。开始我编写上述代码时,也怀疑 new 没有对应的 delete ,将导 致堆内存无法收回,但是,参考VC++5.0的例子 "Hello" ,该程序这部分的代码 与上述无异,也没有其他函数调用delete 回收堆内存,但并不造成内存泄露。 查看VC++的在线帮助,并没有详细的说明,只是说关闭窗口时,自动调用虚函数 PostNCDestory回收m_pMainWnd指向的内存. ---- 于是笔者尝试在主程序类的析构函数中调用 delete m_pMainWnd ,没有效果。显式 调用CWnd::DestoryWindow()也不起作用。参考例子saver, 发现它前面的实现代码 与笔者的完全相同,但是,它在CDrawWnd类中重载了PostNCDestory虚函数,其中 有一行关键的代码: delete this;---- 事实上,是它销毁了CDrawWnd对象。 ---- 于是立刻修改了我的程序,在主窗口类中重载了PostNCDestory函数,加入以上语 句,立刻解决了内存泄露的问题。 ---- 原因终于明白了,原来,如果程序主窗口类是从CFrameWnd继承的,不需要人工 回收类对象占用的内存,象"hello"例子就是这样的程序。但是如果是从Cwnd类 直接继承的主窗口类,就必须考虑这个问题。 strcore.cpp(118) : {2880} normal block at 0x00859390, 992 bytes long. Data: < , 399=> 01 00 00 00 2C 00 00 00 D3 03 00 00 33 39 39 3D strcore.cpp(118) : {2874} normal block at 0x00966EA0, 73 bytes long. Data: < < ->> 01 00 00 00 19 00 00 00 3C 00 00 00 20 20 2D 3E strcore.cpp(118) : {2872} normal block at 0x00966F20, 73 bytes long. Data: < < ->> 01 00 00 00 1D 00 00 00 3C 00 00 00 20 20 2D 3E strcore.cpp(118) : {2870} normal block at 0x00966FA0, 72 bytes long. Data: < ; ->> 01 00 00 00 1C 00 00 00 3B 00 00 00 20 20 2D 3E strcore.cpp(118) : {2868} normal block at 0x00965060, 72 bytes long. Data: < ; ->> 01 00 00 00 1C 00 00 00 3B 00 00 00 20 20 2D 3E strcore.cpp(118) : {2866} normal block at 0x009650E0, 72 bytes long. Data: < ; ->> 01 00 00 00 1C 00 00 00 3B 00 00 00 20 20 2D 3E {2851} normal block at 0x00965580, 20 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {2850} normal block at 0x022E3B70, 3000000 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {2849} normal block at 0x0229002C, 342804 bytes long. Data: <d rK test> 64 00 00 00 E0 72 4B 00 00 00 00 00 74 65 73 74 {2848} normal block at 0x009655C0, 400 bytes long. Data: < > 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 上面是出错信息,但是我看不懂 这个信息提示你在strcore.cpp(118) 分配的内存没有释放,不过strcore.cpp可能是MFC的源代码,这种情况大多是因为CString对象没有释放引起的。一般来说错误信息会有你写的cpp文件。找到你的cpp文件,双击就可以显示这个文件。 normal block at 0x00965580这个又代表什么? 我用 CString str;声明了变量,也要释放? normal block at 0x00965580这种泄漏是用malloc分配的内存,strcore.cpp(118)泄漏通常这样引起:class A{ CString m_str;};然后分配了A的实例,但是没有delete。关键是在泄漏信息中找到你写的cpp文件,如果泄漏信息太多,设法减少这些信息,方法是减少操作,比如打开程序立即关闭。 是不是说我在用了a *b=new a;后才会出先泄露?如果我用a b;声明有没有问题?我程序中好象都是用后面的方法声明的,我觉得应该不会出问题呀 用多线程的时候也有可能出现这种问题。错误信息除了strcore.cpp(118)有没有你的cpp文件。 一般来说,出现内存泄露有两种情况:1。用了NEW,未用DELET释放内存。这比较容易找出。只要你new了,就得delete,他们是成双成对的。另外,如果你new了一个数组,释放形式为delete [] a,(a是变量名)2。用了MFC的一些函数,这些函数要占用一些资源,你的deleteobject或者release。如果你不释放这些资源,一般在调试窗口里可能不会报告错误。 如果你解決不了.發到//[email protected]里.我幫你改.然後告訴你錯在哪裡.new的對象一定要注意在程序退出的時候delete.但是你應該把delete放到正確的位置上.對於模太的應該是在OnDestroy()裡面delete操作對於非模太或者自己定義的.你應該析構在析構里放delete或者free.virtual ~A(); 用new声明的我已经都delete了,至于mfc的类,能不能请各位高手把需要自己delete或释放mfc类在这里给总结一下,这样不只是对我,对其他象我一样的新手也都有不小的帮助。我先写我所知道的唯一一个:CDC 调用DesoryWindow吧,这个道理很容易懂,但你这里的问题不一定是这引起的,信息太少了. 用CMemoryState定位泄漏的地方,注意CSting往往它就是泄漏的元凶,最好将它定义在Doc类下,用指针应用pDoc->str 模拟CTRL+V,但是没有释放CTRL,右边CTRL一直按下状态,求助!!! 诚心的向各位兄弟姐妹请教一下: 如何将一个dialog移至到另一个项目里? 最小化后的郁闷问题!! 不同进程打开同一串口的问题 完成端口的问题? Vc6.0中使用auto_ptr的问题 高分,分不够再给!!!!!!!!!!!!!!! 高分求教:PC/SC中,ISCardCmd::Encapsulate这个方法怎么调用? afx ini Line157如何解决? 如何在应用程序中得到自己的菜单、Toolbar等资源的ID和其他属性? 关于java
后一定要放掉:广告:
小生刚学VC不久,个人认为学好VC不难,但需要多加练习,因此本着这一思想也因个人需要做了这个小程序,此程序也是本人第一个完成的程序,绝无抄袭之处(如有雷同属巧合)或许有许多不足之处,敢请大家指教:)
再且,此程序只有原设想其中一个功能,其它功能正在边学边做当中.有人说这个程序也需注册,对于这一点我不敢苟同,虽然程序简单,但我还是觉得还是有许用处的.而且对于注册功能也是我学习之一.(小生学习VC两月,自觉进步甚多,同时也想在此感谢CSDN各位的大力帮助)http://www10.brinkster.com/cttt/china
m_pMainWnd- >Create(.....);
return TRUE;---- 在调试运行通过后,VC++的调试器报告内存泄露。显然,问题只可能出在上面的 第一行代码上。开始我编写上述代码时,也怀疑 new 没有对应的 delete ,将导 致堆内存无法收回,但是,参考VC++5.0的例子 "Hello" ,该程序这部分的代码 与上述无异,也没有其他函数调用delete 回收堆内存,但并不造成内存泄露。 查看VC++的在线帮助,并没有详细的说明,只是说关闭窗口时,自动调用虚函数 PostNCDestory回收m_pMainWnd指向的内存. ---- 于是笔者尝试在主程序类的析构函数中调用 delete m_pMainWnd ,没有效果。显式 调用CWnd::DestoryWindow()也不起作用。参考例子saver, 发现它前面的实现代码 与笔者的完全相同,但是,它在CDrawWnd类中重载了PostNCDestory虚函数,其中 有一行关键的代码: delete this;---- 事实上,是它销毁了CDrawWnd对象。 ---- 于是立刻修改了我的程序,在主窗口类中重载了PostNCDestory函数,加入以上语 句,立刻解决了内存泄露的问题。 ---- 原因终于明白了,原来,如果程序主窗口类是从CFrameWnd继承的,不需要人工 回收类对象占用的内存,象"hello"例子就是这样的程序。但是如果是从Cwnd类 直接继承的主窗口类,就必须考虑这个问题。
Data: < , 399=> 01 00 00 00 2C 00 00 00 D3 03 00 00 33 39 39 3D
strcore.cpp(118) : {2874} normal block at 0x00966EA0, 73 bytes long.
Data: < < ->> 01 00 00 00 19 00 00 00 3C 00 00 00 20 20 2D 3E
strcore.cpp(118) : {2872} normal block at 0x00966F20, 73 bytes long.
Data: < < ->> 01 00 00 00 1D 00 00 00 3C 00 00 00 20 20 2D 3E
strcore.cpp(118) : {2870} normal block at 0x00966FA0, 72 bytes long.
Data: < ; ->> 01 00 00 00 1C 00 00 00 3B 00 00 00 20 20 2D 3E
strcore.cpp(118) : {2868} normal block at 0x00965060, 72 bytes long.
Data: < ; ->> 01 00 00 00 1C 00 00 00 3B 00 00 00 20 20 2D 3E
strcore.cpp(118) : {2866} normal block at 0x009650E0, 72 bytes long.
Data: < ; ->> 01 00 00 00 1C 00 00 00 3B 00 00 00 20 20 2D 3E
{2851} normal block at 0x00965580, 20 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{2850} normal block at 0x022E3B70, 3000000 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{2849} normal block at 0x0229002C, 342804 bytes long.
Data: <d rK test> 64 00 00 00 E0 72 4B 00 00 00 00 00 74 65 73 74
{2848} normal block at 0x009655C0, 400 bytes long.
Data: < > 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00
上面是出错信息,但是我看不懂
{
CString m_str;
};然后分配了A的实例,但是没有delete。关键是在泄漏信息中找到你写的cpp文件,如果泄漏信息太多,设法减少这些信息,方法是减少操作,比如打开程序立即关闭。
1。用了NEW,未用DELET释放内存。这比较容易找出。只要你new了,就得delete,他们是成双成对的。另外,如果你new了一个数组,释放形式为delete [] a,(a是变量名)
2。用了MFC的一些函数,这些函数要占用一些资源,你的deleteobject或者release。如果你不释放这些资源,一般在调试窗口里可能不会报告错误。
new的對象一定要注意在程序退出的時候delete.但是你應該把delete放到正確的位
置上.
對於模太的應該是在OnDestroy()裡面delete操作
對於非模太或者自己定義的.你應該析構在析構里放delete或者free.
virtual ~A();