Memory Leak in nicht-modalen Dialog
-
Kurz gesagt: Deine Basisklasse könnte in der PostNcDestroy() eigene Aufräumarbeiten erledigen - und die fallen in deinem Code weg. Also mußt du ERST die PostNcDestroy()-Methode der Basisklasse aufrufen und DANACH dein
delete this;einbauen.
-
ich habe jetzt meinen Code abgeändert in
CWnd::OnNcDestroy(); delete->this;hat aber nichts gebracht.
und ein CWnd::PostNcDestroy(); gibt es nicht.
-
sollte vllt mal CDialog::PostNcDestroy versuchen *lol*
steh grad aufem schlauch!!!
-
nee das funktioniert auch nicht!!

-
void CDisplay::PostNcDestroy() { CDialog::PostNcDestroy(); delete this; }was ist daran falsch??
-
Aus meiner Sicht nichts - was sagt denn dein Compiler?
-
der hat nichts zu meckern, compiliert es, nur löst es nicht mein Problem, alles ist wie vorher auch.
-
maRKus23 schrieb:
Vermute ich habe irgendwo ein memory leak in meinem Programm.
Eventuell solltest du dieses "irgendwo" etwas eingrenzen (für eine erste Analyse reicht schon ein
#define new DEBUG_NEW, ansonsten kannst du mal auf die Suche nach einem LeakFinder gehen).
-
was meinst du mit #define new DEBUG_NEW ? was bringt das denn?
-
Damit schaltest du eine Art Heap-Überwachung für dein Programm ein - du setzt die Zeile an den Anfang des Programms und schon wird für jeden new-Aufruf protokolliert, in welcher Programmzeile er war. Und am Ende des Programms gibt dir der Debugger eine Liste aller Speicherbereiche aus, die angefordert, aber nicht freigegeben wurden.
-
ahja werde das dann mal ausprobieren.
-
Die Fehlerbeschreibung klingt IMHO eher nach einem GDI-Ressourcenleck. Ist das der ganze Code von CDisplay?
-
Also ein memory leak ist es nicht, hab ich mit CStoll's vorgeschlagener Methode überprüft.
Nein das ist nicht der ganze Code. Ich kann ja mal aller posten, bis auf die serielle Kommunikation die noch darin steckt, die nehme ich aus platzgründen raus.
-
// Display.cpp : Implementierungsdatei // #include "mainfrm.h" #include "stdafx.h" #include "Par.h" #include "Display.h" #include ".\display.h" // CDisplay-Dialogfeld IMPLEMENT_DYNAMIC(CDisplay, CDialog) CDisplay::CDisplay(CWnd* pParent /*=NULL*/) : CDialog(CDisplay::IDD, pParent) , CTest(_T("")) { } CDisplay::~CDisplay() { } void CDisplay::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_BTN_DISPLAY_CANCEL, m_btnCancel); DDX_Control(pDX, IDC_STATIC_DISPLAY1, m_StaticDisplay1); DDX_Control(pDX, IDC_STATIC_DISPLAY2, m_StaticDisplay2); DDX_Control(pDX, IDC_STATIC_DISPLAY3, m_StaticDisplay3); DDX_Control(pDX, IDC_STATIC_DISPLAY4, m_StaticDisplay4); DDX_Control(pDX, IDC_STATIC_DISPLAY5, m_StaticDisplay5); DDX_Control(pDX, IDC_STATIC_DISPLAY6, m_StaticDisplay6); DDX_Control(pDX, IDC_PICTURE_DISPLAY, m_PictureDisplay); DDX_Control(pDX, IDC_STATIC_LOWER_VALUE, m_Static_LowerValue); DDX_Control(pDX, IDC_STATIC_UPPER_VALUE, m_Static_UpperValue); DDX_Text(pDX, IDC_STATIC_DISPLAY4, CTest); } BEGIN_MESSAGE_MAP(CDisplay, CDialog) ON_WM_CTLCOLOR() ON_BN_CLICKED(IDC_BTN_DISPLAY_CANCEL, OnBnClickedBtnDisplayCancel) END_MESSAGE_MAP() // CDisplay-Meldungshandler void CDisplay::OnBnClickedBtnDisplayCancel() { OnCancel(); } BOOL CDisplay::OnInitDialog() { CDialog::OnInitDialog(); m_font1.CreateFont(-16, 0, 0, 0, FW_BOLD, 0, 0, 0, 1, 0, 0, 0, 0, _T("Arial")); m_font2.CreateFont(-13, 0, 0, 0, FW_BOLD, 0, 0, 0, 1, 0, 0, 0, 0, _T("Arial")); m_StaticDisplay1.SetFont(&m_font2); m_btnCancel.SetFont(&m_font2); m_StaticDisplay2.SetFont(&m_font2); m_StaticDisplay3.SetFont(&m_font2); m_StaticDisplay4.SetFont(&m_font2); m_StaticDisplay5.SetFont(&m_font2); m_StaticDisplay6.SetFont(&m_font1); m_Static_LowerValue.SetFont(&m_font2); m_Static_UpperValue.SetFont(&m_font2); return true; } HBRUSH CDisplay::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { hbr1 = CreateSolidBrush(RGB(253, 170, 130)); hbr2 = CreateSolidBrush(RGB(238, 238, 220)); if ((pWnd->GetDlgCtrlID()==IDC_STATIC_DISPLAY4) || (pWnd->GetDlgCtrlID()==IDC_STATIC_DISPLAY5)) { pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0, 0, 0)); return hbr1; } if((pWnd->GetDlgCtrlID()==IDC_STATIC_DISPLAY1) || (pWnd->GetDlgCtrlID()==IDC_STATIC_DISPLAY2) || (pWnd->GetDlgCtrlID()==IDC_STATIC_DISPLAY3) || (pWnd->GetDlgCtrlID()==IDC_STATIC_DISPLAY6) || (pWnd->GetDlgCtrlID()==IDC_STATIC_LOWER_VALUE) || (pWnd->GetDlgCtrlID()==IDC_STATIC_UPPER_VALUE)) { pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0, 0, 0)); return hbr2; } return hbr2; } void CDisplay::SetValueScale() { char buffer[20]; CString szLowerValue; CString szUpperValue; _gcvt(fValueScale[0], 5, buffer); szLowerValue = buffer; m_Static_LowerValue.SetWindowText(szLowerValue); _gcvt(fValueScale[1], 5, buffer); szUpperValue = buffer; m_Static_UpperValue.SetWindowText(szUpperValue); } /* Änderungen für nicht modales Fenster */ void CDisplay::InitialDialog(const CString& strTitle) { UpdateData (FALSE); SetWindowText(strTitle); } CDisplay* CDisplay::Instance(BOOL* bpCancel, CWnd* pParentWnd) { BOOL bWOldState=FALSE; ASSERT(bpCancel!=NULL); if (bpCancel==NULL) return NULL; CDisplay* pWDlg = new CDisplay; if (pParentWnd==NULL) pWDlg->m_pParentWnd = AfxGetApp()->m_pMainWnd; else { pWDlg->m_pParentWnd = pParentWnd; } if (!pWDlg->Create(IDD_VIEW_DISPLAY, pWDlg->m_pParentWnd)) { delete pWDlg; pWDlg=NULL; return NULL; } if (pWDlg->m_pParentWnd != NULL) bWOldState = pWDlg->GetParentWnd()->EnableWindow(FALSE); pWDlg->EnableWindow (TRUE); if (bWOldState) pWDlg->m_bOldEnableState=FALSE; else pWDlg->m_bOldEnableState=TRUE; pWDlg->m_pbCancel= bpCancel; pWDlg->ShowWindow(SW_SHOW); return pWDlg; } void CDisplay::Done() { if (::IsWindow(GetSafeHwnd())) { OnCancel(); } } void CDisplay::OnCancel() { notifyCancel(); if (m_pParentWnd!=NULL) GetParentWnd()->EnableWindow(m_bOldEnableState); if (::IsWindow(GetSafeHwnd())) DestroyWindow(); } void CDisplay::PostNcDestroy() { CDialog::PostNcDestroy(); delete this; } void CDisplay::OnCancelMode() { CDialog::OnCancelMode(); }
-
Bei jedem Aufruf von OnCtlColor erstellst du zwei Brushs. Und irgendwann gehen Windows die Pinsel aus.
Es wäre besser, wenn du das nur einmal machst, und die Brushs auch wieder freigibst, wenn du sie nicht mehr brauchst (DeleteObject).
-
Habs auch grad erkannt und geändert. Und siehe da, kaum macht mans richtig, funktionierts auch schon.
Danke an MFK und CStoll!!!