Speicherleck bei Thread



  • 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