相当奇怪的内存泄漏

kenshu 2013-08-25 06:08:00
新建一个基于"Dialog based"的工程.

这个工程中,再建一个CDialog ,CTest

----------------------------------

void CAbcDlg::OnOK()
{
// TODO: Add extra validation here
long i,j;
j = 10000;
for (i = 0;i<j;i++){
CString ls_temp;
ls_temp.Format("%d",i);
this->SetWindowText(ls_temp);
CTest lc;
lc.DoModal();
}
// CDialog::OnOK();
}


----------------------------------
CTest中两个事件,纯粹就是为了测试方便,显示后立刻关闭:

void CTest::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default

if (nIDEvent == 1){
this->KillTimer(1);
this->OnCancel();
return;
}
CDialog::OnTimer(nIDEvent);
}

BOOL CTest::OnInitDialog()
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here
this->SetTimer(1,1,NULL);

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

----------------------------------
Release编译,运行之后,这个EXE在资源管理器中,内存使用一直会加上去,并且不再降下来.

//CTest如果是一个空的窗口,内存泄漏不是很明显,但如果在上面加一些控件(全部没有任何代码).
我这里加的是
2个"Group Box"
3个"CButton"
1个"Tree Control"
2个"Combo Box"
4个"Static Text"
...全文
249 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
showxhz 2013-08-27
  • 打赏
  • 举报
回复
刚才看了下你的代码,出现内存泄露确实有点奇怪。 仔细看了下,发现一个问题,就是你的IDD_TEST_DIALOG对话框中的控件都没有定义在对话框中,即使对话框被你delete了,那些资源可能也不能删除,所以造成了内存泄露。 建议 你把这些控件定义到对话框中,测试下
kenshu 2013-08-27
  • 打赏
  • 举报
回复
那就是说,一般的窗口都有一些内存丢掉了?(自己再造一个车轮显然是不可能的) 难道要手工画这些控件,再手动处理拖拽啊什么的的些东西的座标?//如果这真是VC的BUG,这样做当然还是有内存泄漏,只是少一点.
你妹的特盗不 2013-08-27
  • 打赏
  • 举报
回复
这个是vs2008 在win7 64bit下面用mfc CDialog 向导创建的程序,只增加了一句 include <vld.h> 然后编译运行.
'tttt.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\user32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\gdi32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\lpk.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\usp10.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\msvcrt.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\advapi32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\sechost.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\sspicli.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\cryptbase.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\comdlg32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\shlwapi.dll'
'tttt.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\shell32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\winspool.drv'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\oledlg.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\ole32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\oleaut32.dll'
'tttt.exe': Loaded 'C:\Program Files (x86)\Visual Leak Detector\bin\vld.dll'
'tttt.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4940_none_d08cc06a442b34fc\msvcr80.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\imm32.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\msctf.dll'
'tttt.exe': Loaded 'C:\Program Files (x86)\Visual Leak Detector\bin\dbghelp.dll'
Visual Leak Detector Version 1.9d installed.
'tttt.exe': Loaded 'C:\Windows\SysWOW64\uxtheme.dll'
'tttt.exe': Loaded 'C:\Windows\SysWOW64\dwmapi.dll'
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 64 at 0x02D08AD8: 40 bytes ----------
  Call Stack:
The program '[3648] tttt.exe: Native' has exited with code 0 (0x0).
kenshu 2013-08-27
  • 打赏
  • 举报
回复
引用 10 楼 lfs09 的回复:
这个问题,如果你用那个 Visual Leak Detector 检测工具 mfc 的dialog 向导创建的程序都有内存泄漏的……搞不懂.
引用 11 楼 schlafenhamster 的回复:
同意 “你用那个 Visual Leak Detector 检测工具”
那你们的意思是说,这个问题一定会存在? 一般的情况下,是不需要打开10000个窗口的. 但我现在要解决的问题是,一个窗口(相当于一幢楼),还要动态打开多个属性页(相当于这幢楼的多层楼),每个属性页中有数十个到100左右的控件/*也是动态Create的*/(相当于一层楼的房间),每个房间中有多个CStatic. (本身这个窗口有其它固定的控件)这时,这些动态打开的窗口的数量就可观了. 多次打开关闭,内存的增量明显. 所以需要大量测试内存是否泄漏.我一直调了几天,认为是自己程序代码的问题,可是,当我把所有代码关掉(包括动态生成的控件),依然会有内存丢失了.
kenshu 2013-08-27
  • 打赏
  • 举报
回复
引用 12 楼 Sandrer 的回复:
试试直接调用 EndDialog() 而不用 OnCancel() 试试
试了一下,this->EndDialog(IDCANCEL),内存还是不断加上去世。 我试了直接手动按ESC来关闭,也不行。
kenshu 2013-08-27
  • 打赏
  • 举报
回复
引用 17 楼 showxhz 的回复:
刚才看了下你的代码,出现内存泄露确实有点奇怪。 仔细看了下,发现一个问题,就是你的IDD_TEST_DIALOG对话框中的控件都没有定义在对话框中,即使对话框被你delete了,那些资源可能也不能删除,所以造成了内存泄露。 建议 你把这些控件定义到对话框中,测试下
您是指 MFC ClassWizard->Member Variables->Add variable... 把一个实例变量绑定到一个控件上吗? 我一会试试,但相信不是这个原因。 因为,大部份人编程的习惯下,CStatic/CButton ,一般也不会绑定.
引用 18 楼 flydreamGG 的回复:
我测试了下,的确有内存增长的情况,但是句柄却没增加。 我用VS2008 32位WIN7 vld 2.0也没有测出内存泄露。 初步判断: OnCancel是个虚函数,其调用EndDialog来关闭对话框,而EndDialog“只是设置标记,跳出模态对话框的消息循环,但没销毁窗口句柄”,真正的销毁是要通过DestroyWindow发送WM_DESTROY消息来销毁,但这个时候父窗口的消息泵已被你阻塞在for循环,没办法响应,所以对话框没有真正的销毁。
我尝试了一下,不在按钮中FOR循环,而是通过 SetTimer(足够的时间,比如一秒) OnTimer 来做,这样就一定不会阻塞消息,但内存还是上去了.
昨夜无风 2013-08-27
  • 打赏
  • 举报
回复
我测试了下,的确有内存增长的情况,但是句柄却没增加。 我用VS2008 32位WIN7 vld 2.0也没有测出内存泄露。 初步判断: OnCancel是个虚函数,其调用EndDialog来关闭对话框,而EndDialog“只是设置标记,跳出模态对话框的消息循环,但没销毁窗口句柄”,真正的销毁是要通过DestroyWindow发送WM_DESTROY消息来销毁,但这个时候父窗口的消息泵已被你阻塞在for循环,没办法响应,所以对话框没有真正的销毁。
Sandrer 2013-08-26
  • 打赏
  • 举报
回复
试试直接调用 EndDialog() 而不用 OnCancel() 试试
kenshu 2013-08-26
  • 打赏
  • 举报
回复
引用 7 楼 oyljerry 的回复:
GDI资源等是否都释放了。
完整的工程在这里: http://www.shuct.net/down.asp?id=20130826073921&check=AFAC2E0AF36ED2F53BE55BB5C54B3102 其中,只有 void CAbcDlg::OnOK() 是必须的,它用于重复打开 CTest; CTest中的两个函数可以完全不要,只用一个重的东西压在键盘的[Esc]上,手动关闭它. 但就算这样,内存还是会不断上去
schlafenhamster 2013-08-26
  • 打赏
  • 举报
回复
同意 “你用那个 Visual Leak Detector 检测工具”
你妹的特盗不 2013-08-26
  • 打赏
  • 举报
回复
这个问题,如果你用那个 Visual Leak Detector 检测工具 mfc 的dialog 向导创建的程序都有内存泄漏的……搞不懂.
kenshu 2013-08-25
  • 打赏
  • 举报
回复
引用 7 楼 oyljerry 的回复:
GDI资源等是否都释放了。
这是一个空的程序,只有三个函数: 分别是窗口一的,CAbcDlg::OnOK() //负责多次打开窗口二. 窗口一的,void CTest::OnTimer(UINT nIDEvent) / BOOL CTest::OnInitDialog() //负责关掉自己
oyljerry 2013-08-25
  • 打赏
  • 举报
回复
GDI资源等是否都释放了。
kenshu 2013-08-25
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
“CTest lc;” 本身没 释放 放for 外 试试: CString ls_temp; CTest lc; for (i = 0;i<j;i++) { ls_temp.Format("%d",i); this->SetWindowText(ls_temp); lc.DoModal(); }
补充一下,实际需要的是,测试一个窗口,多次创建销毁,是否有内存泄漏. 所以放在FOR 外面,测试不到(FOR 外面的话,必须用指针)
引用 4 楼 schlafenhamster 的回复:
CTest lc 里有没有 new 什么 ,而没 释放 ?
我其实怀疑是我哪里处理得不好,调了好多天,原来的窗口,一句句关掉,最后发现空窗口也会,所以专门写一个小程序来测试。 本身这个程序只是为了测试,没有多余的代码。
kenshu 2013-08-25
  • 打赏
  • 举报
回复
引用 4 楼 schlafenhamster 的回复:
CTest lc 里有没有 new 什么 ,而没 释放 ?
这个程序是专门拿来测试的,没有代码, CTest 中只有两个事件 void CTest::OnTimer(UINT nIDEvent) BOOL CTest::OnInitDialog() 它们是为了窗口可以自己关掉,方便测试.
schlafenhamster 2013-08-25
  • 打赏
  • 举报
回复
CTest lc 里有没有 new 什么 ,而没 释放 ?
kenshu 2013-08-25
  • 打赏
  • 举报
回复
如果定义在FOR外面,我这里必须使用 指针,(我是指我真正的程序需要这样) 因为直正的窗口,CTest::CTest() / CTest::~CTest() 需要做一些处理, FOR 外面定义 CTest lc; 会有问题。//也许可以改原来的程序,但这个应该和内存泄漏没有关系. 而且,就算是您说的 “CTest lc;” 本身没 释放的问题,在退出这个函数后,道理上,也应该会释放,但实际没有 。第二次调用这个函数的时候,内存还是往上走.
kenshu 2013-08-25
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
“CTest lc;” 本身没 释放 放for 外 试试: CString ls_temp; CTest lc; for (i = 0;i<j;i++) { ls_temp.Format("%d",i); this->SetWindowText(ls_temp); lc.DoModal(); }
我在更早前,测试的方法,用的是 CTest * lc; for (i = 0;i<j;i++){ lc = new CTest(); lc->DoModal(); delete lc; } 它也是.
schlafenhamster 2013-08-25
  • 打赏
  • 举报
回复
“CTest lc;” 本身没 释放 放for 外 试试: CString ls_temp; CTest lc; for (i = 0;i<j;i++) { ls_temp.Format("%d",i); this->SetWindowText(ls_temp); lc.DoModal(); }

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧