Speicherleck bei Thread



  • Ich bekomme das Leck nicht raus..werde wohl erstmal zwangsweise auf nen Timer ausweichen. 😮



  • Schon mal probiert m_bAutoDelete auf false zu setzen und dich dannn selbst um die Entsorgung deines CWinThread-Objektes zu kümmern?
    Hatte mal ein ähnliches Problem und das war, warum auch immer, die Lösung.



  • Hi AndyDD,
    ich bin in der Threadsache nicht sehr bewandert muss ich zugeben...

    Du meinst ich soll pThread.m_bAutodelete; dort einfügen, wo ich auch m_Flag=0;
    setze? Mehr nicht?



  • Ich habe das Speicherleck ja insbesondere wenn der Thread läuft...beenden kann ich ihn, dann wird aber kein Speicher freigegeben.

    In der Laufphase powert sich der Speicher dann immer weiter hoch. Habe schon gedacht der Thread wird versehentlich durch einen Fehler
    von mir immer wieder ausgeführt und nicht gekillt. Aber auch das scheint nicht der Fall zu sein, da ich testweise eine MessageBox in die aufzurufende Funktion gepackt habe und die dann nach Beendigung des Thread auch tatsählich nicht mehr kommt...

    😞


  • Mod

    Also m_bAutoDelete ist auf TRUE per defualt.

    An dem was ich an Code hier sehe kann es nicht liegen.
    Ich tippe mal auf einen Fehler in updatelist!
    BTW: Ich sehe nicht, dass die Funktion more komplett hier angegeben wurde.



  • Ist es korrekt dass Du das Leck auch hast, wenn Du void finished::more(void) leer ist?

    Simon



  • Vielleicht ist es das ListControl selbst das mit Daten gefüllt wird..
    Versuch doch mal Abschnitte aus dem Updatelist oder das Updatelist selbst auszukommentieren um die Problemzeilen einzugrenzen..



  • @theta: wenn ich more leer lasse habe ich kein Leck = Speicher unverändert.

    @Martin: in more() ist nicht mehr drin als das hier gepostete.
    Ich kann gerne updatelist() posten..ist ein wildes gefrickel (schonmal sorry dafür!) :

    Egal, man will ja was lernen...los gehts:

    void finished::updatelist(void)
    {
    	m_list1.DeleteAllItems();
    	CString url,saveto;
    	saveto=lnk.pfadzurexe();
    	saveto+="DATA.ini";
    
    	char *pBuf1 = new char[300];
    	CString returnstring1;
    	GetPrivateProfileString("DATA","User","",pBuf1,300,saveto);
    	returnstring1.Format("%s",pBuf1);
    
    	delete []pBuf1;
    
    	char *pBuf12 = new char[300];
    	CString returnstring12;
    	GetPrivateProfileString("DATA","Password","",pBuf12,300,saveto);
    	returnstring12.Format("%s",pBuf12);
    
    	delete []pBuf12;
    
    	char *pBuf13 = new char[300];
    	CString returnstring13;
    	GetPrivateProfileString("DATA","IP","",pBuf13,300,saveto);
    	returnstring13.Format("%s",pBuf13);
    
    	delete []pBuf13;
    
    	char *pBuf14 = new char[300];
    	CString returnstring14;
    	GetPrivateProfileString("DATA","Port","",pBuf14,300,saveto);
    	returnstring14.Format("%s",pBuf14);
    
    	delete []pBuf14;
    
    if(returnstring13!="")
    {
    
    int prt = atoi(returnstring14);
    
    	char *pBuf14a = new char[300];
    	CString returnstring14a;
    	GetPrivateProfileString("DATA","Savein","testpath",pBuf14a,300,saveto);
    	returnstring14a.Format("%s",pBuf14a);
    
    	delete []pBuf14a;
    	returnstring14a.Replace("\\","%2F");
    
    	CInternetSession session;   
    	CHttpConnection* pConnection = session.GetHttpConnection(_T(returnstring13),(INTERNET_PORT)prt,returnstring1,returnstring12);   
    	CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("/cgi-bin/xyz/Gcaller.cgi?set=x"));   
    	BOOL result = pFile->SendRequest(); 
    
    //	bool result =true;
    	url="http://";
    	url+=returnstring13;
    	url+=":";
    	url+=returnstring14;
    	url+="/";
    	url+="cgi-bin/xyz/Gcaller.cgi?set=x";
    
    	int cnt = 0;
    	int curPosxx= 0;
    	int xxcnta =0;
    	CString strHtmlDoc;
    	int curPos = 0;
    	int counter =0;
    	int f =0;
    
    	if(result)
    	{
    
    		char character = NULL;
    
    		CStdioFile* pStdioFile = session.OpenURL(url, 1, INTERNET_FLAG_TRANSFER_BINARY);   
    		int found = -1;
    		while (pStdioFile->Read(&character, 1))         
    		{ 
    
    			strHtmlDoc += character;               
    
    		}
    
    pStdioFile->Close();
    
    		CString zeigen,wert,resToken,vals,del,m_sBody;
    		wert =strHtmlDoc;    
    
    		vals=strHtmlDoc;
    
    		CString str = strHtmlDoc;
    
    		int curPos= 0;
    		int nr =0;
    
    		resToken= str.Tokenize("\n",curPos);
    
    		while (resToken != "")
    		{
    
    		m_sBody=resToken;
    
    		nr++;
    		CString nrcs;
    		nrcs.Format("%i",nr);
    
    			int position1 = m_sBody.Find(',');
    			CString w1=(m_sBody.Left(position1));
    			m_list1.InsertItem(0,nrcs,0);
    			m_list1.SetItemText(0,1,w1);
    
    			int position2=m_sBody.Find(',',position1+1);  
    			CString w2=m_sBody.Mid(position1+1,position2-position1-1); 
    			m_list1.SetItemText(0,2,w2);
    
    			int position3=m_sBody.Find(',',position2+1);  
    			CString w3=m_sBody.Mid(position2+1,position3-position2-1);
    			m_list1.SetItemText(0,3,w3);
    
    			int position4=m_sBody.Find(',',position3+1); 
    			CString w4=m_sBody.Mid(position3+1,position4-position3-1);
    			m_list1.SetItemText(0,4,w4);
    
    			int position5=m_sBody.Find(',',position4+1); 
    			CString w5=m_sBody.Mid(position4+1,position5-position4-1);
    			m_list1.SetItemText(0,5,w5);
    
    			int position6=m_sBody.Find(',',position5+1);
    			CString w6=m_sBody.Mid(position5+1,position6-position5-1);
    			m_list1.SetItemText(0,6,w6);
    
    			int position7=m_sBody.Find("\\",position6+1);
    			CString w7=m_sBody.Right(m_sBody.GetLength()-1-position6);
    			m_list1.SetItemText(0,7,w7);
    
    			resToken= str.Tokenize("\n",curPos);
    		};
    
    		delete pFile;
    
    		delete pConnection;
    
    	session.Close();
    
    	}else
    	{
    		MessageBox("fehler beim senden!");
    	}
    
    }
    
    }
    


    1. pConnection und pFile werden nur gelöscht, wenn die Anfrage erfolgreich gesendet wurde. Ansonsten nicht.

    2. Reicht bei pStdioFile ein Close oder muss es auch gelöscht werden?



  • Zusätzlich kannst Du die char Buffer auch auf dem Stack allozieren, dann werden sei automatisch aufgeräumt.



  • @sri: du meinst delete pStdioFile ?

    @theta: wie meinst du das? 😞


  • Mod

    Ja! Es fehlt ein

    delete pStdioFile;
    

    Siehe Sample:
    http://msdn.microsoft.com/de-de/library/cc485620(VS.71).aspx



  • ForenFan schrieb:

    @sri: du meinst delete pStdioFile ?

    @theta: wie meinst du das? 😞

    So:

    char pBuf1[300] = {}; 
    CString returnstring1; 
    GetPrivateProfileString("DATA","User","",pBuf1,300,saveto); 
    returnstring1.Format("%s",pBuf1);
    

  • Mod

    theta schrieb:

    char pBuf1[300] = {}; 
    CString returnstring1; 
    GetPrivateProfileString("DATA","User","",pBuf1,300,saveto); 
    returnstring1.Format("%s",pBuf1);
    

    Das ist ja auch Code der übeleren Sorte, besser und weitaus einfacher:

    CString returnstring1; 
    GetPrivateProfileString("DATA","User","",CStrBuf(returnstring1,300),300,saveto);
    

    Weiterhin grundsätzlich, warum machst Du so etwas:

    char pBuf1[] = "something"; 
    CString returnstring1; 
    returnstring1.Format("%s",pBuf1);
    

    Warum nicht einfach:

    char pBuf1[] = "something"; 
    CString returnstring1(pBuf1);
    

    oder

    char pBuf1[] = "something"; 
    CString returnstring1;
    returnstring1 = pBuf1;
    


  • Ich wollte mit dem Codeschnipsel nur zeigen, dass die Allokation auf dem Stack gemacht werden kann und nicht auf dem Heap. Aber danke für die schönere, komplette Variante.



  • Hi, ich krame das Thema nochmals hoch, da ich zwischenzeitlich dachte es
    hätte sich erledigt. Dem ist jedoch nicht so...

    Sobald ich das zweite mal in die Updatelist() komme schmiert mir die
    Anwendung mit einem Runtime Error ab.

    Im Debugger lande ich dann in der "memcpy_s.c" dort stehe ich am Ende der
    Datei bei:

    memcpy(dst, src, count); //HIER
        return 0;
    }
    

    Zuvor werden offenbar laut Debugger in Updatelist() diese Zeilen aufgerufen:

    pConnection = session.GetHttpConnection(_T(returnstring13),(INTERNET_PORT)prt,returnstring1,returnstring12); //hier ist wohl das problem
    
    pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("/cgi-bin/xyz/List.cgi?GCaller2=x"));
    

    In inet.cpp wird bei:

    void AFXAPI AfxThrowInternetException(DWORD_PTR dwContext, DWORD dwError /* = 0 */)
    {
    	if (dwError == 0)
    		dwError = ::GetLastError();
    
    	CInternetException* pException = new CInternetException(dwError);
    	pException->m_dwContext = dwContext;
    
    	TRACE(traceInternet, 0, "Warning: throwing CInternetException for error %d\n", dwError);
    	THROW(pException);
    }
    

    Der Fehlercode 28674224 für dwError ausgespuckt.

    Komisch ist, dass ich doch in dem Threadcall auch alles sauber wieder lösche und
    er eigentlich im nächsten durchlauf mit NULL initialisieren müsste und der Fehler so in der Form nicht auftreten dürfte... 😕

    Das hier wird ja alles nach einem Durchlauf in Updatelist() abgearbeitet:

    delete pStdioFile;
    delete pFile;
    delete pConnection;
    session.Close();
    

    Die Deklaration der Variablen CInternetSession etc. habe ich nun alledrings aus der Funktion raus in die Klasse verlegt. Das scheint wohl auch mit Schuld daran zu sein.

    Komisch nur, dass es auch wenn die Deklaration in der selben Funktion liegt, irgendwann nach ca. 10 Minuten mit Runtime Error knallt.


Anmelden zum Antworten