我做了一个控件,在上面进行不断的绘图,有泄漏。我用的编译环境是VS2005,wince嵌入式主板上写的应用。大家帮忙看一下啊,看似哪个地方出错了。还有就是不知道怎么检查内存泄漏。谢谢啊
void alarmdisplay::OnPaint()//状态
{ CPaintDC dc(this); 
extern CTest *pDlgx[55];
pDlgx[52]= NULL;
pDlgx[52]= (CTest *)GetParent();
Lock();
CClientDC dc1(FromHandle(this->m_hWnd));
extern CRect  lpRect,lpRect1;
GetClientRect(lpRect);
if(pen.GetSafeHandle())
{
pen.DeleteObject();
}
if(brush.GetSafeHandle())
{
brush.DeleteObject();
}
if(font1.GetSafeHandle())
{
font1.DeleteObject();
}
brush.CreateSolidBrush(RGB(132,210,255));
dc1.SelectObject(&brush);
dc1.FillRect(lpRect,&brush);
LOGFONT lf;
::ZeroMemory(&lf,sizeof(lf));
lf.lfHeight =(lpRect.bottom)*600/1000;
lf.lfWeight =(lpRect.right)*1200/1000;
lf.lfItalic = FALSE;
wcscpy(lf.lfFaceName,_T("Arial"));
font1.CreateFontIndirect(&lf);
if(pDlgx[52]->alarmnumber>0)
{
if((pDlgx[52]->alarmcur) < (pDlgx[52]->alarmnumber))
{
dc1.SetBkMode(TRANSPARENT);
dc.SetBkMode(TRANSPARENT);
SetBkColor(dc,(RGB(255,0,0)));
dc.SelectObject(&font1);
if(pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur]==_T("LOW POWER"))
{
dc.ExtTextOutW((lpRect.right)*250/1400,-(lpRect.bottom)*20/300,ETO_OPAQUE,NULL,_T("LOW"),NULL);
dc.ExtTextOutW((lpRect.right)*250/1400,(lpRect.bottom)*130/300,ETO_OPAQUE,NULL,_T("POWER"),NULL);
}
else
{
dc.ExtTextOutW((lpRect.right)*50/1400,(lpRect.bottom)*50/300,ETO_OPAQUE,NULL,pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur],NULL);
}
pDlgx[52]->alarmcur++;
}
}
if(pen.GetSafeHandle())
{
delete &pen;
}
if(brush.GetSafeHandle())
{
delete &brush;
}
font1.DeleteObject();
dc1.ReleaseOutputDC();
dc1.ReleaseAttribDC();
dc.ReleaseOutputDC();
dc.ReleaseAttribDC();
dc1.DeleteDC();
dc.DeleteDC();
dc1.DeleteTempMap();
dc.DeleteTempMap();
pen.DeleteTempMap();
brush.DeleteTempMap();
font1.DeleteTempMap();
UnLock();
}

解决方案 »

  1.   

    用IBM 的Ratioanl或者BouderCheck就可以了,
    内存泄露不借助工作很难察的。
      

  2.   

    你这个代码太混乱了,看得都头晕.
    跟你说几个问题吧:
    1 .变量作用域不明白
    //extern CRect  lpRect,lpRect1;
    第二个变量根本没用到,第一个变量其实就是获取一个窗口大小而已,
    而且你是在paint函数获取的,有必要外部引用吗?
    2. 内存管理不清楚
    内存释放一定要是用new 分配的才可以调用delete释放内存,
    你的brush看样子是定义一个对象,是不能delete &brush;
    if(brush.GetSafeHandle()) 

    delete &brush; 

    3. cdc(CDC ,pen,brush等)对象调用创建之后,只要调用DeleteObject删除即可.
    不需要DeleteTempMap(系统会自动调用的),
    它是用来删除FromHandle获得的CDC对象
      

  3.   

    CPaintDC dc(this); 
    extern CTest *pDlgx[55];
    pDlgx[52]= NULL;
    pDlgx[52]= (CTest *)GetParent();
    Lock();
    CClientDC dc1(FromHandle(this->m_hWnd));
    extern CRect  lpRect,lpRect1;
    GetClientRect(lpRect);
    if(pen.GetSafeHandle())
    {
    pen.DeleteObject();
    }
    if(brush.GetSafeHandle())
    {
    brush.DeleteObject();
    }
    if(font1.GetSafeHandle())
    {
    font1.DeleteObject();
    }
    brush.CreateSolidBrush(RGB(132,210,255));
    dc1.SelectObject(&brush);
    dc1.FillRect(lpRect,&brush);
    LOGFONT lf;
    ::ZeroMemory(&lf,sizeof(lf));
    lf.lfHeight =(lpRect.bottom)*600/1000;
    lf.lfWeight =(lpRect.right)*1200/1000;
    lf.lfItalic = FALSE;
    wcscpy(lf.lfFaceName,_T("Arial"));
    font1.CreateFontIndirect(&lf);
    if(pDlgx[52]->alarmnumber>0)
    {
    if((pDlgx[52]->alarmcur) < (pDlgx[52]->alarmnumber))
    {
    dc1.SetBkMode(TRANSPARENT);
    dc.SetBkMode(TRANSPARENT);
    SetBkColor(dc,(RGB(255,0,0)));
    dc.SelectObject(&font1);
    if(pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur]==_T("LOW POWER"))
    {
    dc.ExtTextOutW((lpRect.right)*250/1400,-(lpRect.bottom)*20/300,ETO_OPAQUE,NULL,_T("LOW"),NULL);
    dc.ExtTextOutW((lpRect.right)*250/1400,(lpRect.bottom)*130/300,ETO_OPAQUE,NULL,_T("POWER"),NULL);
    }
    else
    {
    dc.ExtTextOutW((lpRect.right)*50/1400,(lpRect.bottom)*50/300,ETO_OPAQUE,NULL,pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur],NULL);
    }
    pDlgx[52]->alarmcur++;
    }
    }
    dc.DeleteDC();
    delete dc1;
    UnLock();
    我改过了,是这样的吗?
      

  4.   

    CPaintDC dc(this); 
    extern CTest *pDlgx[55]; 
    pDlgx[52]= NULL; 
    pDlgx[52]= (CTest *)GetParent(); 
    Lock(); 
    CClientDC dc1(FromHandle(this->m_hWnd)); 
    extern CRect  lpRect,lpRect1; 
    GetClientRect(lpRect); 
    if(pen.GetSafeHandle()) 

    pen.DeleteObject(); 

    if(brush.GetSafeHandle()) 

    brush.DeleteObject(); 

    if(font1.GetSafeHandle()) 

    font1.DeleteObject(); 

    brush.CreateSolidBrush(RGB(132,210,255)); 
    dc1.SelectObject(&brush); 
    dc1.FillRect(lpRect,&brush); 
    LOGFONT lf; 
    ::ZeroMemory(&lf,sizeof(lf)); 
    lf.lfHeight =(lpRect.bottom)*600/1000; 
    lf.lfWeight =(lpRect.right)*1200/1000; 
    lf.lfItalic = FALSE; 
    wcscpy(lf.lfFaceName,_T("Arial")); 
    font1.CreateFontIndirect(&lf); 
    if(pDlgx[52]->alarmnumber>0) 

    if((pDlgx[52]->alarmcur) < (pDlgx[52]->alarmnumber)) 

    dc1.SetBkMode(TRANSPARENT); 
    dc.SetBkMode(TRANSPARENT); 
    SetBkColor(dc,(RGB(255,0,0))); 
    dc.SelectObject(&font1); 
    if(pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur]==_T("LOW POWER")) 

    dc.ExtTextOutW((lpRect.right)*250/1400,-(lpRect.bottom)*20/300,ETO_OPAQUE,NULL,_T("LOW"),NULL); 
    dc.ExtTextOutW((lpRect.right)*250/1400,(lpRect.bottom)*130/300,ETO_OPAQUE,NULL,_T("POWER"),NULL); 

    else 

    dc.ExtTextOutW((lpRect.right)*50/1400,(lpRect.bottom)*50/300,ETO_OPAQUE,NULL,pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur],NULL); 

    pDlgx[52]->alarmcur++; 


    dc.DeleteDC(); 
    delete dc1; 
    UnLock(); 
    我整理了一下。改过了,可是用delete 的时候老是出错
      

  5.   

    你试试BoundsChecker查找吧,内存泄露嘛,都是必要的经历过程嘛……
      

  6.   

    因为是wince上运行的程序,BoundsChecker不能运行该程序
      

  7.   

    CPaintDC dc(this); 
    CTest *pDlgx=(CTest *)GetParent(); 
    CRect  lpRect; 
    GetClientRect(lpRect); 
    //pen没用到,删除代码
    //brush,没次都相同,没什么变化,建议定义一个全局变量,对话框初始化创建,Destory时删除
    //你的lock是用来干什么的 Lock(); 
    dc.FillRect(lpRect,&brush); 
    LOGFONT lf; 
    ::ZeroMemory(&lf,sizeof(lf)); 
    lf.lfHeight -MulDiv(PointSize, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72);; 
    lf.lfWeight =FW_NORMAL//只有固定的几个值
    lf.lfItalic = FALSE; 
    wcscpy(lf.lfFaceName,_T("Arial"));
    CFont font; 
    font.CreateFontIndirect(&lf); 
    if(pDlgx->alarmnumber>0) 

        if(pDlgx->alarmcur < pDlgx->alarmnumber) 
        { 
            dc.SetBkMode(TRANSPARENT); 
            dc.SetBkColor(RGB(255,0,0)); 
            CFont* pOldFont=dc.SelectObject(&font); 
            if(pDlgx->alarmstrText[pDlgx[52]->alarmcur]==_T("LOW POWER")) 
            { 
               dc.ExtTextOutW((lpRect.right)*250/1400,-(lpRect.bottom)*20/300,ETO_OPAQUE,NULL,_T("LOW"),NULL); 
               dc.ExtTextOutW((lpRect.right)*250/1400,(lpRect.bottom)*130/300,ETO_OPAQUE,NULL,_T("POWER"),NULL); 
            } 
           else 
           { 
              dc.ExtTextOutW((lpRect.right)*50/1400,(lpRect.bottom)*50/300,ETO_OPAQUE,NULL,pDlgx->alarmstrText[pDlgx->alarmcur],NULL); 
           } 
           dc.SelectObject(pOldFont);
           pDlgx->alarmcur++; 
         } 

     font.DeleteObject();
      

  8.   

    只有一个建议 DC的声明和定义放到ONPAINT外头去,省时又可以避免泄露
      

  9.   

    CBrush* oldburhs = dc1.SelectObject(&brush); 
    用完之后要 dc1.SelectObject(oldburhs )选回来,
    再释放brush,不然系统一直占用这brush根本就没有释放掉。
      

  10.   

    那么我程序里面的dc使用delete &dc呢还是用dc.deleteDC();我有些不太明白
      

  11.   

    一般来说dc.CreateCompatibleDC()出来的就用dc.deleteDC()。
      

  12.   

    CPaintDC dc(this); 
    extern CTest *pDlgx[55];
    pDlgx[52]= NULL;
    pDlgx[52]= (CTest *)GetParent();
    Lock();
    CClientDC dc1(FromHandle(this->m_hWnd));
    extern CRect  lpRect,lpRect1;
    GetClientRect(lpRect); if(pen.GetSafeHandle())
    {
    pen.DeleteObject();
    }
    if(brush.GetSafeHandle())
    {
    brush.DeleteObject();
    }
    if(font1.GetSafeHandle())
    {
    font1.DeleteObject();
    } brush.CreateSolidBrush(RGB(132,210,255));
    CBrush *pOldbrush = dc1.SelectObject(&brush);
    dc1.FillRect(lpRect,&brush);
    dc1.SelectObject(pOldbrush);
    LOGFONT lf;
    ::ZeroMemory(&lf,sizeof(lf));
    lf.lfHeight =(lpRect.bottom)*600/1000;
    lf.lfWeight =(lpRect.right)*1200/1000;
    lf.lfItalic = FALSE;
    wcscpy(lf.lfFaceName,_T("Arial"));
    font1.CreateFontIndirect(&lf); if(pDlgx[52]->alarmnumber>0)
    {
    if((pDlgx[52]->alarmcur) < (pDlgx[52]->alarmnumber))
    {
    dc1.SetBkMode(TRANSPARENT);
    SetBkColor(dc1,(RGB(255,0,0)));
    CFont *pOldfont = dc1.SelectObject(&font1);
    if(pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur]==_T("LOW POWER"))
    {
    dc1.ExtTextOutW((lpRect.right)*250/1400,-(lpRect.bottom)*20/300,ETO_OPAQUE,NULL,_T("LOW"),NULL);
    }
    else
    {
    dc1.ExtTextOutW((lpRect.right)*50/1400,(lpRect.bottom)*50/300,ETO_OPAQUE,NULL,pDlgx[52]->alarmstrText[pDlgx[52]->alarmcur],NULL);
    }
    dc1.SelectObject(pOldfont);
    pDlgx[52]->alarmcur++;
    }
    }
    if(pen.GetSafeHandle())
    {
    pen.DeleteObject();
    }
    if(brush.GetSafeHandle())
    {
    brush.DeleteObject();
    }
    if(font1.GetSafeHandle())
    {
    font1.DeleteObject();
    } dc1.DeleteDC();
    dc.DeleteDC();
    UnLock();
    还是有问题啊