Problem bei Freigabe dynamisch allokierten Speichers



  • Hallo zusammen, ich schreibe aus tiefer Verzweiflung heraus und hoffe hier (erneut) Hilfe zu finden.

    Um zunächst einmal direkt auf das Problem zu kommen:

    Ich allokiere zunächst einmal etwas Speicher um Bilddaten aus einem
    File in den Speicher zu kopieren.

    char * buffer = new char[size];
    

    später, wenn ich das Bild nicht mehr brauche, lösche ich den Speicher
    wieder mit

    delete[] lpSurface->pixels;
    

    Man kann hier schon erahnen, dass ich SDL nutze und die vorher geladenen Bytes
    mit Hilfe der Funktion

    SDL_CreateRGBSurfaceFrom(buffer,width,height,bpp,pitch,NULL,NULL,NULL,NULL);
    

    in einem Surface als Grafikdaten referenziert habe, aber da ich mir nicht wirklich sicher bin ob das ein SDL-spezifisches Problem ist, poste ich vorsichtshalber mal hier.

    Mein Problem ist, dass der Speicher einfach nicht freigegeben wird.
    Ich nutze den "Process Explorer" von http://www.sysinternals.com/
    um den Speicherverlauf meiner Applikation zu überwachen.

    Ich habe, da meine Applikation schon recht komplexe Züge angenommen hat, ein kleines Testprogramm geschrieben welches eben erläutertes Szenario in Kurzform
    darstellt und dort funktioniert das Ganze.

    Also muss der Fehler ja woanders liegen....

    Nach endlosem debuggen habe ich dann mal die Eingebung gehabt, doch einmal die Adressen des allokierten Speichers mit dem des zu befreienden Speichers zu vergleichen: Sie sind identisch. Das ist auch der Grund warum ich hier poste.

    Ich bin am Ende (mit meinem C++) und wollte mein kleines Spiel eigentlich Ende diesen Monats veröffentlichen.

    Wo kann da der Fehler liegen kann, wenn doch die Adressen des Speichers identisch sind?!??!!? 😡

    Vielleicht nützt ja die Zusatzinformation, dass eine Referenz eines Objectes, in welchem sich letztlich auch der Zeiger auf den allikierten Speicher befindet, in einem <vector> gespeichert wird.
    Aber selbst das habe ich in meinem Testprogramm implementiert, ohne Erfolg.

    Ich würde mich sehr freuen, wenn irgendjemand meine(n) Fehler findet.

    Bis dahin aber erstmal
    Tschüss,

    Nils



  • Schau Dir mal den Code an, der den Puffer bearbeitet, vielleicht hast Du ueber den Anfang oder das Ende des Puffers geschrieben, und dadurch die Speicherliste veraendert. Dann kann es z.B. passieren, dass beim Freigeben nix passiert. Oder dass es einen Absturz gibt.



  • Hallo,

    Ich nehme mal an lpSurface ist ein Pointer auf SDL_Surface. Hast du diesen Speicher dann mit SDL_FreeSurface auch noch freigegeben oder ist die Surface vielleicht gelockt?



  • // Allokieren des Speichers
    char * buffer = new char[size];
    
    // Füllen des Speichers
    file.read(buffer,size);
    
    // Löschen des Speichers
    delete [] buffer;
    

    @PowerOff:
    Oben siehst Du den Codeeausschnitt, der die Daten lädt. Ich habe zum Test mal die Freigabe des Speichers direkt nach dem Laden der Daten aufgerufen, jedoch ist bleibt der Speicher vorhanden, was ich einerseits daran erkenne, dass der Process-Monitor keine Veränderung anzeigt und andererseits daran, dass die Bilder im Spiel zu sehen sind.

    @Braunstein:
    Mit obigem Test fällt leider auch Deine gute Idee flach.

    Schon komisch, vielleicht hab ich was ganz grundlegendes in der Deklaration/Definition falsch ?



  • Oppodelldog schrieb:

    @PowerOff:
    Oben siehst Du den Codeeausschnitt, der die Daten lädt. Ich habe zum Test mal die Freigabe des Speichers direkt nach dem Laden der Daten aufgerufen, jedoch ist bleibt der Speicher vorhanden, was ich einerseits daran erkenne, dass der Process-Monitor keine Veränderung anzeigt und andererseits daran, dass die Bilder im Spiel zu sehen sind.

    Oh Mann!! Du hast gar kein Problem!!

    Da Du den Speicher ueber new [] allokiert hast, wurde er ja in der Speicherverwaltung der C++ Library allokiert, und die nimmt immer ganze Bloecke vom Betriebssystem, gibt sie aber nicht unmittelbar wieder frei. Dadurch zeigt natuerlich der Prozess-Monitor keine Veraenderung.

    Ausserdem kann es durchaus sein, dass in den Speicher nichts neues geschrieben wird, solange kein neuer Speicher von Deinem Programm allokiert wird.

    Allokier mal nach der Freigabe einen Speicherblock aehnlicher Groesse und fuelle den mit ein paar Daten.



  • Jedoch stört mich dass quasi "nie" Speicher freigegeben wird.
    Ich hab das Programm was eigentlich bei max. 10 MB laufen sollte mal
    bis 50 MB hochgepushed.
    Wann wird denn dann der Speicher freigegeben ?
    Bzw gibts denn keinen Weg den Speicher zu kontrollieren ?

    Und wieso wird in meinem kleinen Testprogramm dann der Speicher sofort beim Aufruf

    delete [] buffer;
    

    freigegeben ?



  • Wieviele Threads hast Du in Deinem Programm? Jeder Thread kostet ca. 4 MB Adressraum, weil das OS eine ganze Page fuer den Stack allokiert (im virtuellen Speicher).

    Die C/C++ Standard Bibliothek allokiert ganze Pages, oder jedenfalls groessere Bloecke vom OS und zerteilt diese. Die Page wird erst dann freigegeben, wenn kein Speicherblock mehr darauf allokiert ist.

    Entweder Du machst Dir eigene new- und delete-Operatoren (siehe Stroustrup-Buch, und/oder "new.h"), oder vwerwendest eine spezielle Library oder spezielle Programme (wie z.B. Boundschecker), um den Speicherverbrauch zu ueberwachen. Dann siehst Du auch, wieviel tatsaechlich verbraucht wird in jedem Moment.

    Weiterhin kann auch sein, dass die SDL Library grosszuegig mit dem Speicher umgeht, oder so.

    Unter welchem OS entwickelst Du? Windows oder Linux?



  • Mein Programm läuft mit 8 Threads.
    Ich entwickle unter Windows2000.

    Also wenn das so ist, das es an den Bibliotheken liegt die ich verwende, dann
    nehme ich das mal so hin :-), obwohl ich das eigentlich nicht so hinnehmen will, dass ein Programm 40MB Speichermüll behält.
    Ich dachte halt ich hab irgendwo irgendwie ein Leak, aber wenns an den Pages liegt, nun gut. Dann verlass ich mich mal auf Windows und bin gespannt auf die Ergebnisse unter anderen Betriebssystemen.

    Ist der Boundschecker nicht von der Firma mit den lustigen Vertretern ?
    🙂 Ist mir als Privatmann zu teuer.

    Wie dem auch sei,
    danke für Eure/Deine Mühe



  • So, um diesen Thread für die Zukunft zu vervollständigen werde ich hier nun die Lösung des Problems posten.

    Power Off schrieb:

    Oh Mann!! Du hast gar kein Problem!!
    ...

    Weit gefehlt ;), denn ich hatte ein Problem namens MSVC

    Ich habe mein Projekt mit doch recht wenig Aufwand *selbstaufschulterklopf* nach DEVCPP gewuchtet und Tadaaa es läuft alles so wie es soll.

    Gute Nacht


Anmelden zum Antworten