注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

告别迷茫

梦想与现实的差距,就是我们生活的意义。因为我们有差距,我们才会一直积累,在努力。

 
 
 

日志

 
 

【转载】[经验之谈]关于MFC中CVSListBox类在子类化时候的内存泄露  

2015-01-25 10:07:34|  分类: 孙鑫VC++升入详解 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
我之前发现CMFCButton类在子类化的时候会有内存泄露,网上也有很多人在讨论这个问题,并给出了一些解决办法。

参见:【VS2010】CMFCBUTTON使用过程中发生内存泄露  

[经验之谈]关于MFC中CVSListBox类在子类化时候的内存泄露 - lvan - lvan GoGo 的世界
这一次发现的是CVSListBox类出现的内存泄露,复现场景是:
1. 新建一个类CNewVSListBox,继承自 CVSListBox。
2. 往对话框上拖动一个
CVSListBox控件,并绑定一个 CNewVSListBox的成员变量。
这个时候就会出现内存泄露了。

后面我又重做了一下,发现只需要上面的第二步就能复现这个情况。看来是真的和CMFCButton类有关了。

这个控件类的继承很奇妙,可以仔细研究一下它的实现。它的上面有四个按钮(并且还可以添加删除新按钮),这四个按钮都是CMFCButton类对象。那么呢首先我会怀疑是不是这四个按钮引起的内存泄露呢?而且内存显示确实是4个tooltip控件对象未被释放。
起码数量上对上了。开始查吧。

中间的查找过程记不起来了,大家看看前面的一篇文章就知道调试有多难了。直接说结果吧。呵呵。

1. 首先拖动到对话框上的控件在对话框开始创建的时候就会创建,然后再进行控件子类化。这样首先会创建一个
CVSListBox对象,然后被 CNewVSListBox类型子类化。
2. 在这个过程中,有一个消息被发送了两次,能猜到吧。就是那个
WM_MFC_INITCTRL消息。这个罪魁祸首!!在VS2010之前的MFC类库中是没有这个消息的,后来才被加进去,没想到这一下搞出问题来了。你说吧,说是微软的Bug,但是程序员可以自己解决;说不是微软的Bug吧,心里面又用着不舒服。

我的解决办法是:
将对话框上的
CVSListBox 控件替换成动态创建的 CNewVSListBox对象,然后就解决了。还需要调用它的SetStandardButtons函数显示上面的那4个按钮。

发现问题并解决问题真的不容易呀!![经验之谈]关于MFC中CVSListBox类在子类化时候的内存泄露 - lvan - lvan GoGo 的世界



如果使用VS2010创建Dialog程序使用了上面的控件,并且App类继承自CWinApp,应该还会报告

Detected memory leaks!
Dumping objects ->
{494} client block at 0x0077F418, subtype c0, 212 bytes long.
a CMFCVisualManager object at $0077F418, 212 bytes long
Object dump complete.

这个问题很简单,只需要在App类的InitInstance函数最后调用CMFCVisualManager::DestroyInstance()。
  评论这张
 
阅读(87)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017