[内存问题]VC中Client Block at的问题...路过的都进来看看吧

一个基于对话框的MFC程序...
在程序退出的时候 出现内存泄露 具体信息如下:

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp(4500) : {405} client block at 0x005DE4E8, subtype c0, 56 bytes long.
a CObject object at $005DE4E8, 56 bytes long
Object dump complete.

找到wincore.cpp的4500行(红色代码), 具体代码如下:
BOOL CWnd::ExecuteDlgInit(LPVOID lpResource)
{
// Subclass Feature Pack controls: 
if (m_pMFCCtrlContainer == NULL)
{
m_pMFCCtrlContainer = new CMFCControlContainer (this);
m_pMFCCtrlContainer->SubclassDlgControls ();
}
  ...
  ...
  ...

}

问题是出在那个new的地方?
具体该怎么在我自己的代码中检测呢?
我用的是VS2010... 希望各位帮忙出出主意啊

作者: hello_stranger   发布时间: 2011-01-12

1、m_pMFCCtrlContainer 没有delete
2、vs编译时没有办法检测,只有运行后会提示泄露

作者: varding   发布时间: 2011-01-12

同意1楼的说法,new完就要记得delete

作者: fqzlala   发布时间: 2011-01-12

引用 1 楼 varding 的回复:

1、m_pMFCCtrlContainer 没有delete
2、vs编译时没有办法检测,只有运行后会提示泄露

问题是wincore.cpp是MFC内部的代码 不是我自己写的
如何检测到是哪个对话框初始化的时候 调用了ExecuteDlgInit函数?
{405} client block at 0x005DE4E8
{}内的405是内存分配序号么? 如何定位呢?
有时候{}内是403 
这个纠结啊

作者: hello_stranger   发布时间: 2011-01-12

_CrtSetBreakAlloc(405),MFC内部应该也是调用了crt的内存分配

作者: lostying   发布时间: 2011-01-12

可能是对话框没有正常释放,你的对话框应该是new出来的,对吗?

作者: eyey1   发布时间: 2011-01-12

405是内存块编号,这个应该是变的,看你申请内存的顺序了

你是不是窗口没有正确的关闭?

作者: varding   发布时间: 2011-01-12

引用 4 楼 lostying 的回复:

_CrtSetBreakAlloc(405),MFC内部应该也是调用了crt的内存分配

watch里面添加上面的CRT调试代码 找不到...

作者: hello_stranger   发布时间: 2011-01-12

引用 5 楼 eyey1 的回复:

可能是对话框没有正常释放,你的对话框应该是new出来的,对吗?

我的对话框 都是自己定义 然后DoModal出来的

作者: hello_stranger   发布时间: 2011-01-12

引用 6 楼 varding 的回复:

405是内存块编号,这个应该是变的,看你申请内存的顺序了

你是不是窗口没有正确的关闭?

程序的主界面中响应WM_CLOSE消息的代码 我都是发送WM_CLOSE消息结束的
void CCageDlg::OnClose()
{
// CreateSession dialog
if ( m_pDlgNewSession )
{
m_pDlgNewSession->SendMessage( WM_CLOSE, 0, 0);

if ( m_pDlgNewSession->m_pPickProxyDlg )
{
m_pDlgNewSession->m_pPickProxyDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( m_pDlgNewSession->m_pPickPlayerDlg )
{
m_pDlgNewSession->m_pPickPlayerDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( m_pDlgNewSession->m_pConfirmDlg )
{
m_pDlgNewSession->m_pConfirmDlg->SendMessage( WM_CLOSE, 0, 0);
}
}

// Pending page
if ( GetPendingPage().m_pPlayerInfoDlg )
{
GetPendingPage().m_pPlayerInfoDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( GetPendingPage().m_pPickProxyDlg )
{
GetPendingPage().m_pPickProxyDlg->SendMessage( WM_CLOSE, 0, 0);
}

// Buy-In page
if ( GetBuyInPage().m_pBuyInDlg )
{
GetBuyInPage().m_pBuyInDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( GetBuyInPage().m_pPlayerInfoDlg )
{
GetBuyInPage().m_pPlayerInfoDlg->SendMessage( WM_CLOSE, 0, 0);
}

// Active page
if ( GetActivePage().m_pPlayerInfoDlg )
{
GetActivePage().m_pPlayerInfoDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( GetActivePage().m_pSessionInfoDlg )
{
GetActivePage().m_pSessionInfoDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( GetActivePage().m_pAddBuyInDlg )
{
GetActivePage().m_pAddBuyInDlg->SendMessage( WM_CLOSE, 0, 0);
}

if ( GetActivePage().m_pBuyOutDlg )
{
GetActivePage().m_pBuyOutDlg->SendMessage( WM_CLOSE, 0, 0);
}

CDialogEx::OnClose();
}

作者: hello_stranger   发布时间: 2011-01-12

引用 7 楼 hello_stranger 的回复:

引用 4 楼 lostying 的回复:

_CrtSetBreakAlloc(405),MFC内部应该也是调用了crt的内存分配

watch里面添加上面的CRT调试代码 找不到...

那段是加在程序里面的代码,最好在WinMain里面就调用,MFC就在initInstance里面.
如果是在watch窗口的话,应该是{,,msvcr90d.dll}_crtBreakAlloc,其中msvcr90d.dll替换成你的程序加载的crt动态库,直接设置这个变量的值就行了.断电的话你可以在mfc的源码appinit.cpp里面的AfxWinInit的开始处设置一个,或者直接到ctrexe.c里面直接设到mainCRTStartup处.

作者: lostying   发布时间: 2011-01-12