Anzeige:
Ergebnis 1 bis 8 von 8

Thema: C++ Memory Leaks

  1. #1
    Registrierter Benutzer
    Registriert seit
    29.09.2005
    Beiträge
    6

    C++ Memory Leaks

    Hallo Forum
    Ich lese bereits einige Zeit hier mit, doch nun habe ich ein merkwürdiges Problem, für das ich Hilfe benötige. Desshalb habe ich mich entschlossen mich hier zu registrieren!

    Zu meinem Problem: in einem Programm von mir (edit: ein C++ Programm) entstehen ziemlich viele Speicherleichen und ich verstehe nicht so ganz wieso. Im prinzip gehts da darum, ein Array zu kopieren, zu ändern und dann zurückzukopieren. Dazu habe ich ein Pointerarray von denen jeder auf ein Objekt zeigt. So kann ich beim zurückkopieren nur die Pointer ändern. Ich habe die betr. Funktion hier einmal skizziert:

    Code:
    SomeClass ** object;   //Wird sonstwo alloziert und initialisiert....
    
    function()
    {
       SomeClass ** copy;
       
       copy = new SomeClass*[SIZE];    //alloziere Pointerarray
       for( int i = 0; i < SIZE; i++)
       {
          copy[i] = new SomeClass;        //alloziere Objekt
          * copy[i] = * object[i];            //erstelle eine Kopie
       }
    
       doSomeMutations( copy );          //verändere die Kopien
       
       //hier vertausche ich Pointer von Original und Kopie.
       //Ich kann das Original nicht sofort löschen, da es im
       //Originalquelltext mehr Kopien als Originale gibt, von 
       //denen nur eine Auswahl zurückkopiert wird. Ansonsten
       //wären am Schluss immer noch vorige Kopien im Speicher. 
       //Desshalb soll erst ganz am Schluss alles wieder 
       //freigegeben werden.
       for( int i = 0; i < SIZE; i++)
       {
          SomeClass * swap = object[i];  //merke die Pos. des Originals
          object[i] = copy[i];                 //ersetze das Original durch die Kopie
          copy[i] = swap;                      //speichere die Pos. d. Originals
       } 
       
       //gibt den nicht mehr gebrauchten Speicher frei
       for( int i = 0; i < SIZE; i++ )
          delete [] copy[i];
       delete [] copy;
    
    }
    Ev. habe ich die Verwendung von delete immer noch nicht so ganz begriffen.
    Muss der Destruktor meiner Klasse "SomeClass" selber dafür sorgen, dass
    der Speicher frei wird?

    Wenn nicht könnt ihr den Fehler entdecken.

    gruss
    oli

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Sieht für mich ok aus (d.h. aber nicht dass nicht ein C++-Guru hier noch was finden könnte )

    copy[i] = new SomeClass; //alloziere Objekt
    * copy[i] = * object[i]; //erstelle eine Kopie

    eventuell macht da der Zuweisungsoperator was blödes? Wieso verwendest du nicht direkt den Copy-Constructor?

    copy[i] = new SomeClass(*object[i]);

    (C++ generiert automatisch einen, der memberweise kopiert)

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Registrierter Benutzer
    Registriert seit
    29.09.2005
    Beiträge
    6
    Zitat Zitat von peschmae
    eventuell macht da der Zuweisungsoperator was blödes? Wieso verwendest du nicht direkt den Copy-Constructor?

    copy[i] = new SomeClass(*object[i]);
    Weil ich den Operator überschrieben habe. Denn es müssen nicht alle Members kopiert werden. Viele können auch einfach auf 0 stehen, da sie eh gleich neu berechnet werden müssen.

  4. #4
    Registrierter Benutzer Avatar von SeeksTheMoon
    Registriert seit
    22.02.2002
    Beiträge
    762
    kannst ja mal valgrind nachprüfen lassen
    I haven't lost my mind - It's somewhere on a backup-disc

  5. #5
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Code:
    SomeClass ** copy;
       
       copy = new SomeClass*[SIZE];    //alloziere Pointerarray
       for( int i = 0; i < SIZE; i++)
       {
          copy[i] = new SomeClass;        //alloziere Objekt
          * copy[i] = * object[i];            //erstelle eine Kopie
       }
    Das kann Speicherlecks verursachen wenn irgendeine, abgesehen von der ersten new-Operation fehlschlägt. Denn in dem Fall wird nirgendwo der Speicher freigegeben. In "Produktionscode" solltest du irgendwie damit umgehen.
    Code:
    for( int i = 0; i < SIZE; i++)
       {
          SomeClass * swap = object[i];  //merke die Pos. des Originals
          object[i] = copy[i];                 //ersetze das Original durch die Kopie
          copy[i] = swap;                      //speichere die Pos. d. Originals
       }
    Jetzt hast du die Element in "object" und die in "copy" ausgetauscht. Das ist soweit Okay, aber bist du dir sicher, dass du die Elemente in "object" auch wieder freigibst?

    Code:
    for( int i = 0; i < SIZE; i++ )
          delete [] copy[i];
       delete [] copy;
    Da steckt mit großer Wahrscheinlichkeit ein Fehler drin, und wenn ja, dann ist es ein schwerwiegender: Es sieht so aus, als ob du Elemente die mit "new" angelegt wurden, mit "delete[]" wieder freigegeben werden sollen. Das geht nicht.

    Zitat:
    Zitat von peschmae
    eventuell macht da der Zuweisungsoperator was blödes? Wieso verwendest du nicht direkt den Copy-Constructor?

    copy[i] = new SomeClass(*object[i]);
    Weil ich den Operator überschrieben habe. Denn es müssen nicht alle Members kopiert werden. Viele können auch einfach auf 0 stehen, da sie eh gleich neu berechnet werden müssen.
    Hört sich nicht gut an. Ich halte es für wahrscheinlich, dass du irgendwelche kruden Sachen mit Copy-Constructor oder Zuweisungsoperator machst. Überleg mal, ob man das nicht doch verbessern kannst. "Überschrieben" ist übrigens ein Ausdruck den du nicht verwenden solltest. Es ist nicht klar was du damit meinst, z.B. könnte sowohl die Bedeutung von "Überladung" also auch von "Overriding" in Frage kommen. Ich würde im Allgemeinen ja von "override" ausgehen, aber in deinem Beispiel scheint das irgendwie nicht zu passen, denn ein Copy-Constructor kann ja nicht virtuell sein, und virtuelle Zuweisungsoperatoren trifft man in in "freier Wildbahn" selten an.

  6. #6
    Registrierter Benutzer
    Registriert seit
    29.09.2005
    Beiträge
    6
    so es hat sich erledigt...

    Ich hatte einen leeren Defaultdestructor, daher wurden wohl die Members nicht gelöscht.

  7. #7
    Registrierter Benutzer
    Registriert seit
    29.09.2005
    Beiträge
    6
    Zitat Zitat von locus vivendi
    Code:
    for( int i = 0; i < SIZE; i++ )
          delete [] copy[i];
       delete [] copy;
    Da steckt mit großer Wahrscheinlichkeit ein Fehler drin, und wenn ja, dann ist es ein schwerwiegender: Es sieht so aus, als ob du Elemente die mit "new" angelegt wurden, mit "delete[]" wieder freigegeben werden sollen. Das geht nicht.
    wieso nicht?

    gruss
    oli

  8. #8
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    delete[] ist für Speicher, der mit new[] angefordert wurden, nicht für Speicher, der mit new angefordert wurde.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •