none
Memory leak finden, wenn sich die Speicherblocknummer ständig ändert RRS feed

  • Frage

  • Ich habe ein memory leak, das ich versuche mittels

    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );


    zu ermitteln. Leider ohne Erfolg. Die Quellcodezeilenangabe bleibt aus. Versuche ich dann den Memory Block im Debugger zu finden über

    //Memory leak Debugging
    _CrtSetBreakAlloc(<Block>);

    stellt sich heraus, dass sich die Blocknummer mit jedem Neustart des Programms verändert. Wie kann man so was beikommen?

    Besten Dank,

    Thomas

    Samstag, 29. März 2014 16:47

Antworten

  • Na, dann schu Dir den MFC code mal genauer an. :)

    Logisch, das Deine Überschreibung einen Leak erzeugt.

    In OnDeestroy wird SetPaneText(iNULL,FALSE); verwendet um den Speicher in den Panes freizugeben. Da Du aber bei NULL immer wieder Deinen Text hineinballerst wird der Speicher nie freigegeben.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

    • Als Antwort markiert milonass Montag, 7. April 2014 07:22
    Montag, 7. April 2014 06:31
    Moderator

Alle Antworten

  • Gar nicht ist glaube ich seit win 7 by Design.
    Sonntag, 30. März 2014 08:04
  • Nein, dass ist nicht bei Design, sondern nur in den Codeteilen der Fall in denen DEBUG-NEW nicht gesetzt wird.

    Und das sind oft einige auch eigene Codeteile oder templates etc.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

    Montag, 31. März 2014 08:16
    Moderator
  • Grenze das ganze ein indem Du Snapshots verwendest.

    Siehe http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

    _CrtMemState, _CrtMemCheckpoint, _ CrtMemDumpStatistics

    Siehe auch
    http://msdn.microsoft.com/en-us/library/d41t22sb.aspx

    _CrtDumpMemoryLeaks calls _CrtMemCheckpoint to obtain the current state of the heap and then scans the state for blocks that have not been freed. When an unfreed block is encountered, _CrtDumpMemoryLeaks calls _CrtMemDumpAllObjectsSince to dump information for all the objects allocated in the heap from the start of program execution.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

    Montag, 31. März 2014 08:20
    Moderator
  • Ich hab es tatsächlich gefunden: Die überschriebene Methode

    BOOL CMFCStatusB::SetPaneText(int nIndex, LPCTSTR text, BOOL bUpdate )
    {
    
    	if (text == NULL || *text == _T('\0'))
    	{
    		/*CString Text = CString(MAKEINTRESOURCE(AFX_IDS_IDLEMESSAGE));
    		text = Text;*/
    
    		text = _T("Für Hilfe F1 drücken...");
    	}
    	
    
    	HICON hIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ANNOTATE_INFO), IMAGE_ICON, 32, 32, 0);
    	this->SetPaneIcon(0,hIcon,1);	
    	DestroyIcon(hIcon);
    	
    	return CMFCStatusBar::SetPaneText(nIndex,text)

    produziert das Leck. Egal ob ich die CString Variante oder die andere verwende. Kommentiere ich aber auch den Teil

    text = _T("Für Hilfe F1 drücken...");
    
    aus, entsteht kein Leck.

    Was ist hier falsch?

    Danke.

    Thomas



    • Bearbeitet milonass Dienstag, 1. April 2014 20:14
    Dienstag, 1. April 2014 19:51
  • Schön das Du das Leck finden konntest.
    Ich glaube nicht, dass mit der statischen Variante ein Leck entsteht.

    Schau doch mal was die nächste Basis-Funktion macht, evtl. leaked ja dort was in der MFC.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

    Mittwoch, 2. April 2014 06:29
    Moderator
  • Die Funktion SetPaneText holt sich eine Referenz auf die CMFCStatusBarPaneInfo und setzt direkt die Membervariable lpszText. Das passiert genau viermal, weil es vier Pane-Bereiche mit Text gibt. Deswegen gibt es auch vier Leaks. Mir ist aber noch nicht klar, ob ich etwas tun kann, das zu verhindern.

    BOOL CMFCStatusBar::SetPaneText(int nIndex, LPCTSTR lpszNewText, BOOL bUpdate)
    {
    	ASSERT_VALID(this);
    
    	CMFCStatusBarPaneInfo* pSBP = _GetPanePtr(nIndex);
    	if (pSBP == NULL)
    	{
    		return FALSE;
    	}
    
    	if (pSBP->lpszText != NULL)
    	{
    		if (lpszNewText != NULL && lstrcmp(pSBP->lpszText, lpszNewText) == 0)
    		{
    			return TRUE;        // nothing to change
    		}
    
    		free((LPVOID)pSBP->lpszText);
    	}
    	else if (lpszNewText == NULL || *lpszNewText == '\0')
    	{
    		return TRUE; // nothing to change
    	}
    
    	BOOL bOK = TRUE;
    	if (lpszNewText == NULL || *lpszNewText == '\0')
    	{
    		pSBP->lpszText = NULL;
    	}
    	else
    	{
    		pSBP->lpszText = _tcsdup(lpszNewText);
    		if (pSBP->lpszText == NULL)
    			bOK = FALSE; // old text is lost and replaced by NULL
    	}
    
    	if (bUpdate)
    	{
    		InvalidatePaneContent(nIndex);
    	}
    
    	return bOK;
    }

     
    Freitag, 4. April 2014 13:36
  • Na, dann schu Dir den MFC code mal genauer an. :)

    Logisch, das Deine Überschreibung einen Leak erzeugt.

    In OnDeestroy wird SetPaneText(iNULL,FALSE); verwendet um den Speicher in den Panes freizugeben. Da Du aber bei NULL immer wieder Deinen Text hineinballerst wird der Speicher nie freigegeben.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

    • Als Antwort markiert milonass Montag, 7. April 2014 07:22
    Montag, 7. April 2014 06:31
    Moderator
  • O.k., danke. Ich habe jetzt eine andere Lösung gefunden, die den Text über das Frame Window setzt. Dennoch: Liegt nicht unbedingt auf der Hand, in OnDestroy SetPaneText aufzurufen, oder? Es ist aus meiner Sicht naheliegend, diese Funktion zu überschreiben. So wie das umgesetzt ist, geht das aber nicht.
    Montag, 7. April 2014 07:21
  • Gebe ich Dir recht. Hier hätten die Low-Level Speicher einfach freigegeben werden müssen...

    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

    Mittwoch, 9. April 2014 06:09
    Moderator