内存泄露解决记录——窗口资源释放

本文详述了解决MFC程序内存泄露中关于窗口资源释放的问题,包括推荐使用DestroyWindow销毁窗口,重载PostNcDestroy进行析构,以及窗口对象与句柄的释放与分离。同时介绍了HWND的概念、引用计数的重要性以及DestroyWindow函数的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间在解决代码的内存泄露问题,解决了部分内存泄露问题。

 

http://blog.youkuaiyun.com/enjolras/archive/2011/01/05/6117628.aspx

这篇文章起到了很好的指引作用,让我对MFC里宏观方面的释放有了一定了解。

总结一下就是:

1、推荐用DestroyWindow来销毁窗口(或者从窗口派生的对象)。

2、重载PostNcDestroy函数通过调用基类的PostNcDestroy函数,如:Cwnd::PostNcDestroy,以及通过delete this来调用析构函数(析构函数中处理窗口类中的需要delete的成员)来自动清理。

 

此外比较重要的几点(需要好好理解的几点):

1、Windows对象(CWnd派生类的对象)既代表一个C++对象(在应用程序的堆中分配)也代表了一个HWND(由窗口管理器在系统资源里分配)。释放分为如下部分,C++对象的释放,HWND的释放,以及C++对象与与之关联的句柄的分离过程(detach)。

 

2、当销毁一个Windows窗口时,最后发送给此窗口的Windows消息是WM_NCDESTROY。CWnd对此消息的缺省处理(CWnd::OnNcDestroy)会将C++对象与HWND分离,并调用虚函数PostNcDestroy

 

3、缺省的CWnd析构函数会在m_hWnd不为空的情况下调用DestoryWindow,但这不会导致无穷递归,因为此句柄在清除阶段将会处于分离状态并为空。注意是缺省的,若重载了析构函数将不会调用。

 

### 使用Valgrind检测和修复内存泄漏 #### 安装Valgrind 为了能够使用Valgrind进行内存泄漏检测,首先需要安装该工具。对于大多数Linux发行版来说,可以通过包管理器轻松完成这一操作。 ```bash sudo apt-get install valgrind ``` #### 编译带有调试信息的程序 编译待测程序时应加入`-g`选项以包含调试信息,这有助于Valgrind更精确地定位问题所在的位置[^1]。 ```bash gcc -g myprogram.c -o myprogram ``` #### 运行Valgrind检测内存泄漏 执行下面命令启动Valgrind,并指定要测试的应用程序及其参数。这里使用的是Memcheck工具,默认情况下Valgrind会自动加载此工具来进行内存错误检查。 ```bash valgrind --leak-check=full ./myprogram arg1 arg2... ``` 上述命令将会运行目标应用并输出详细的内存泄漏报告至终端窗口。报告内容涵盖了泄露的内存块详情、具体尺寸以及可能引发这些漏洞的源码位置等重要数据[^2]。 #### 解析Valgrind报告 当收到由Valgrind产生的日志文件之后,应当仔细阅读其中的信息以便准确定位潜在的问题区域。每一条记录都提供了关于何时何地分配了哪些资源却没有被适当回收的关键线索。例如: - **Definitely lost**: 明确存在的内存泄漏。 - **Indirectly lost**: 由于其他直接丢失的对象而间接失去引用的对象集合。 - **Possibly lost**: 可能存在但无法确认的情况;通常这类情况也需要关注。 - **Still reachable**: 虽然当前仍然可以访问但是理论上应该已经被释放掉的部分。 针对每一类别的提示采取相应的措施去修正代码逻辑上的缺陷,确保所有动态申请的空间都能得到妥善处理,在不再需要的时候及时释放它们[^3]。 #### 修改代码消除内存泄漏 依据Valgrind给出的结果调整有问题的地方,比如增加必要的`free()`语句来清理不再使用的堆上分配的数据结构体成员变量或是数组元素等等。务必保持良好的编程习惯——即每次malloc/new之后都要有对应的free/delete配对出现于同一作用域内或是在对象生命周期结束之前显式销毁之。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值