Speicher wird nicht freigegeben



  • Hallo!

    Kann mir jemand sagen, warum der reservierte Speicher bei folgendem Codeausschnitt nicht freigegeben wird?

    LPSTR FILEHANDLER::GetPathFromJobIni(int i, BOOL bGetFromDone)
    {
    	TCHAR * cBuffer= new TCHAR[MAX_PATH];	// Buffer to recieve the path
    	char cI[6];
    	sprintf(cI, "%d", i);
    	LPSTR szIniFile;						
    
    	//	Set job file path to either done or current
    	if(bGetFromDone)
    	{
    		szIniFile= this->szIniDone;
    	}
    	else
    	{
    		szIniFile= this->szIniJobs;
    	}
    
    	// Get job's filename from jobs file
    	GetPrivateProfileString(cI, this->szPathKeyName, "", cBuffer, MAX_PATH, szIniFile);
    
    	// Return the job's filename
    	return cBuffer;
    }
    
    static unsigned long __stdcall ConverterThread(void* instance)
    {
    	CONVJOB cj;
    	while(1)
    	{
    	fh.GetPathFromJobIni(0, FALSE);	// o.g. Funktion in Schleife ausführen	
    	}
    	return 0;
    }
    

    Beim Ausführen dieses Codes steigt der reservierte Speicher für den Prozess kontinuierlich an und ist innerhalb weniger Minuten auf ein paar Gigabyte.

    Gruß veryxRV



  • veryxRV schrieb:

    Kann mir jemand sagen, warum der reservierte Speicher bei folgendem Codeausschnitt nicht freigegeben wird?

    Warum sollte er freigegeben werden? Zum Freigeben findet sich nichts im Code. Da ist nur ein new, kein delete. Schönes Speicherleck.



  • Dein Code sieht übrigens kopiert aus.
    Versuch dich erstmal an leichte Sachen.


  • Mod

    Vor alem verstehe ich nicht den Sinn, der hier ein durch new allokierter Buffer hat. Wenn es um einen Pfad geht, häte sein Zeiger auf einen Buffer mit der Größe _MAX_PATH auch genügt.



  • Wie MFK schon gesagt hat,
    das muss New sein, nicht delete -.-"
    Ist doch auch eig. verständlich^^
    Aber trotzdem wünsch ich dir viel Erfolg bei deinem Projekt 😉



  • pivke schrieb:

    Dein Code sieht übrigens kopiert aus.
    Versuch dich erstmal an leichte Sachen.

    Nein, ist alles auf meinem Mist gewachsen. Ist ja auch nicht so, als wäre ich Anfänger, nur wie schwer zu erkennen ist, habe ich vom Umgang mit Speicher kaum Ahnung.

    pivke schrieb:

    Wie MFK schon gesagt hat,
    das muss New sein, nicht delete -.-"
    Ist doch auch eig. verständlich^^
    Aber trotzdem wünsch ich dir viel Erfolg bei deinem Projekt 😉

    Na was denn jetzt? 😉

    Ich dachte nur, der Speicher wird automatisch wieder freigegeben, weil er durch das beenden der Funktion seine Gültigkeit verliert... 😕 Wie soll man das auch anders machen? Ich kann die Variable ja schlecht zurückgeben, wenn ich sie vorher gelöscht habe 😉



  • Ich spiel jetzt mal linker.
    Hier findest du bestimmt auh was über Binren Speicher.
    www.robsite.de



  • Also: Der Rückgabewert von FILEHANDLER::GetPathFromJobIni ist mit

    delete [] mein_wert;
    

    freizugeben.

    Wenn du kein Bock auf diese Speicherfreigabe hast, dann solltest du

    TCHAR * cBuffer= new TCHAR[MAX_PATH];
    

    umwandeln in

    static TCHAR cBuffer[MAX_PATH] = {0};
    

    😉



  • Okay danke 🙂

    An welcher Stelle muss ich denn das delete anbringen? Nach dem return macht ja keinen Sinn.


  • Mod

    Wenn Du einen Zeiger so returnierst in der aufrufenden Funktion, wo sonst?
    Deshlab mach wie ich es gesagt habe. Übergib einen entsprechenden Zeiger auf einen TCHAR Array der Größe _MAX_PATH und gut ists!



  • Du rufst GetPathFromJobIni auf und wenn du den Rückgabewert nicht mehr brauchst, löschst du ihn; bspw.:

    TCHAR *pszValue = GetPathFromJobIni (1, TRUE);
    ...
    // Mache irgendetwas mit pszValue
    ...
    delete [] pszValue;
    

    Martins Lösung ist typischer für die WinApi:

    // Deklaration
    void GetPathFromJobIni (int i, BOOL bGetFromDone, TCHAR *pBuffer, int nMaxBuffer);
    
    // Aufrufen:
    TCHAR buffer[MAX_PATH] = {0};
    
    GetPathFromJobIni (1, TRUE, buffer, MAX_PATH);
    ...
    // Mache irgendetwas mit buffer
    ...
    

    Dann entfernst du die Definition von "cBuffer" aus der Methode "GetPathFromJobIni" und ersetzt die restlichen "cBuffer" durch "pBuffer" (=> s. neue Übergabeargumente)



  • Okay vielen Dank soweit, ich werde morgen mal schauen, wie ich damit zurechtkomme! 🙂



  • Gut, das funktioniert soweit 🙂 Aber eine Frage habe ich noch: Wie kann ich ganze Instanzen von Klassen wieder freigeben?



  • Keine Idee?

    Ich habe eine Klasse erstellt, die diverse Pointer enthält, die wieder freigegeben müssen. Ich würde aber gerne die gesamte Klasse freigeben, anstatt jeden Wert einzeln.



  • geht nicht


  • Mod

    veryxRV schrieb:

    Keine Idee?

    Ich habe eine Klasse erstellt, die diverse Pointer enthält, die wieder freigegeben müssen. Ich würde aber gerne die gesamte Klasse freigeben, anstatt jeden Wert einzeln.

    Schon mal was von einem Destruktor gehört?
    Ansonsten muss man sehen was und wie Du das mit den Zeigern machst.
    Also zeige und Code.



  • @veryxRV: std::auto_ptr, boost::scoped_ptr, boost::shared_ptr, ...


Anmelden zum Antworten