Speicherleck im Thread



  • Moin. Ich habe einen Thread geschrieben, der Musikdateien finden soll. Soweit so gut. Leider bekomme ich jedoch Speicherlecks:

    Detected memory leaks!
    Dumping objects ->
    {266} normal block at 0x001EAE88, 64 bytes long.
     Data: <  9             > C4 FC 39 01 17 00 00 00 17 00 00 00 01 00 00 00 
    Object dump complete.
    

    Hier die betroffene Zeile in der MFC-Klassen-Funktion CPlex::Create():

    CPlex* p = (CPlex*) new BYTE[sizeof(CPlex) + nMax * cbElement];
    

    Hier der Thread:

    UINT CMainDlg::SearchThrd(LPVOID pParam)
    {
    	CMainDlg *pThis = reinterpret_cast<CMainDlg*>(pParam);
    
    	pThis->m_btnStop.EnableWindow(true);
    
    	CStringList lstDirs;
    	CString sRootDir;
    	pThis->m_editSearchPath.GetWindowText(sRootDir);
    	lstDirs.AddTail(sRootDir);
    
    	while(!lstDirs.IsEmpty() && !pThis->m_bStopThread)
    	{
    		CString sFileName, sExtension;
    		CFileFind cFileFind;
    		BOOL bFound = cFileFind.FindFile(lstDirs.GetHead() + _T("\\*.*"));
    
    		while(bFound && !pThis->m_bStopThread)
    		{
    			bFound = cFileFind.FindNextFile();
    
    			if(cFileFind.IsDots())
    				continue;
    
    			if(cFileFind.IsDirectory())
    			{
    				lstDirs.AddTail(cFileFind.GetFilePath());
    				continue;
    			}
    
    			sFileName = cFileFind.GetFileName();
    			sExtension = sFileName.Right(sFileName.GetLength() - sFileName.ReverseFind(_T('.')) - 1);
    
    			if(sExtension.CompareNoCase(_T("mp3")) && sExtension.CompareNoCase(_T("wma")) && sExtension.CompareNoCase(_T("ogg")))
    				continue;
    
    			pThis->m_lstFoundFiles.AddTail(cFileFind.GetFilePath());
    			pThis->m_u4NumFoundFiles++;
    			pThis->Update();
    		}
    
    		lstDirs.RemoveHead();
    	}
    
    	pThis->m_btnStop.EnableWindow(false);
    
    	AfxEndThread(EXIT_SUCCESS);
    	return EXIT_SUCCESS;
    }
    

    Nun bin ich ehrlichgesagt ein wenig ratlos, was falschlaufen könnte, weil ich den Heap ja gar nicht bewusst benutze... Es hat wohl irgendwas mit einer Collection, also vielleicht lstDirs zu tun, aber sicher bin ich mir da nicht. Sieht einer einen Fehler oder kann mir Tipps zur weiteren Fehlersuche geben?

    Besten Dank.



  • an welcher Stelle gibst du CPlex* p mit delete wieder frei? ich würde sagen du hast die Speicherfreigabe vergessen



  • Hat zwar nichts mit deinem Problem zu tun, aber man sollte nicht im Workerthread auf GUI-Elemente zugreifen.
    Das hier

    schwerminator schrieb:

    pThis->m_btnStop.EnableWindow(true);
    

    ist so ein Zugriff. Ich sehe ähnlich wie CTecS auch keine Freigabe deines mit new angeforderten Speichers.


  • Mod

    Nein! Er hat nichts vergessen, aber erhat durch den Aufruf von AfxEndThread seinen Destruktoren keine Chance gegeben zum aufrufen.

    Der Aufruf von AfxEndThread ist absolut faösch. Einfach return und gut ist.

    BTW: Es wurde schon gesagt. Die Vermendung von UI Thread und workerthread ist fatal. Dann kannst Du Dir auch den zweiten Thread sparenund einfach zwischen drin RedrawWindow/UpdateWindow aufrufen.



  • Martin Richter schrieb:

    Nein! Er hat nichts vergessen, aber erhat durch den Aufruf von AfxEndThread seinen Destruktoren keine Chance gegeben zum aufrufen.

    Der Aufruf von AfxEndThread ist absolut faösch. Einfach return und gut ist.

    BTW: Es wurde schon gesagt. Die Vermendung von UI Thread und workerthread ist fatal. Dann kannst Du Dir auch den zweiten Thread sparenund einfach zwischen drin RedrawWindow/UpdateWindow aufrufen.

    Hallo Martin, du hast recht; nachdem ich AfxEndThread() herausgenommen habe, funktioniert's tadellos. Allerdings habe ich natürlich auch die entsprechenden MSDN-Seiten gelesen und da steht folgendes:

    http://msdn.microsoft.com/en-us/library/2s21xzfe(v=VS.80).aspx schrieb:

    For a worker thread, normal thread termination is simple: Exit the controlling function and return a value that signifies the reason for termination. You can use either the AfxEndThread function or a return statement. Typically, 0 signifies successful completion, but that is up to you.

    Allerdings steht auf einer anderen Seite der Community-Content:

    http://msdn.microsoft.com/en-us/library/s96hway2(VS.80).aspx schrieb:

    AfxEndThread call's _endthread so destructors will not be called.

    link to the bugreport on microsoft connect:

    http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=356209

    Das mit dem Zugriff auf die GUI-Elemente war erstmal quick&dirty dahingepfuscht, aber danke für den Hinweis.


Anmelden zum Antworten