Programmieren mit qt: new vs. delete

Dieses Thema im Forum "C/C++" wurde erstellt von rikola, 18.01.2007.

  1. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Ich gucke mir grade ein paar Beispiele zu Qt4.2 an, zum Beispiel dieses hier. Dabei faellt auf, dass sehr selten, manchmal nie, der Speicher, der mit 'new' angefordert wurde, wieder freigegeben wird. Dieser thread behauptet zwar, dass man sich nicht darum kuemmern muesse, da die Elternwidgets sich um das Loeschen der Kinder kuemmern (wobei ich selbst das bezweifle, da beim Freigeben eines Zeigers ja nicht der Speicherbereich freigegeben wird, auf den er zeigt, wenn man nicht delete benutzt!). Allerdings sehe ich z.B. in obigem Beispiel nicht, dass die Widgets als Kinder erzeugt werden (parent=0 als default), ausserdem gibt es nicht mal ein einziges delete.

    Muss man sich unter Qt nicht darum kuemmern, weil man davon ausgeht, dass nicht so viele Fenster erzeugt werden/ geloescht werden, dass man in den Bereich von Speicherproblemen kommen koennte, ist die Programmiertechnik unter den Qt-Tutorials nicht die optimalste, oder uebersehe ich etwas Entscheidendes?
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. hehejo

    hehejo blöder Purist

    Dabei seit:
    12.10.2003
    Beiträge:
    1.280
    Zustimmungen:
    0
    Ort:
    Stein (Mittelfranken)
    Ich sag's mal kurz:
    malloc&free, new&delete sind USERSPACE.
    Sobald dein Programm beendet wird räumt der Kernel eh alles auf.

    Wenn du z.B. ein free oder ein delete machst, wird nicht zwingend wieder Speicher an den Kernel zurückgegeben.
    Sieh dir dazu mal man sbrk an.

    Man kann es auch so sagen:
    Wenn du weißt, dass dieses Programm nicht lange läuft, kannste auf's delete verzichten. Ist halt nur nicht sauber.
     
  4. #3 slash-ex, 18.01.2007
    slash-ex

    slash-ex Doppel-As

    Dabei seit:
    04.10.2006
    Beiträge:
    130
    Zustimmungen:
    0
    boa das wäre der inbegriff des schlechten proggens und kann speicherlecks erzeugen das ist dir klar! ich habe zwar lange nicht mehr programmiert (studium der biologie fordert immens viel zeit) aber ich weiß das zum. bei qt3 ein fehlendes delete einen spez. einfluss nahm.... ich hatte auch mal bei qtforum.de was drübergelesen... hmm denkedenke... mir fällt nichts mehr ein...

    probiers einfach mal aus.. ob dein programm wirkl einen destr. erzeugt wenn dus beendest. und vergiss nicht. das du für alle non-widgets unbedingt ein delete anhängen solltest.

    generell ist es guter stil ein eigenen destruktor zu erzeugen bzw. an best. stellen das nicht. benötigte widget zu zerstören um das programm evtl. schon zur laufzeit schlanker zu machen.

    und dann sei noch gesagt das du nicht weißt wohin du das prog. portieren willst. nicht jedes os räumt auf!
     
  5. hehejo

    hehejo blöder Purist

    Dabei seit:
    12.10.2003
    Beiträge:
    1.280
    Zustimmungen:
    0
    Ort:
    Stein (Mittelfranken)
    *hust* Ich _weiß_ dass dies schlechter Stil ist.
    Und alles was nicht aufräumt ist für mich kein OS.
     
  6. #5 pinky, 18.01.2007
    Zuletzt bearbeitet: 18.01.2007
    pinky

    pinky König

    Dabei seit:
    11.08.2004
    Beiträge:
    795
    Zustimmungen:
    0
    Um wieder zum eigentlichen Thema zurück zu kommen. Alle Widgets die du in dem Beispiel mit new erzeugst sind "Teil" des Hauptfensters bzw. haben am Ende das Hauptfenster als Eltern-Widget. Wenn das Hauptfenster gelöscht wird, werden von Qt automatisch auch alle Kinder sauber abgeräumt. Da alle Widgets als Teil des Hauptfensters so lange Leben wie das Hauptfenster selber brauchst du in diesem Beispiel also nie ein delete.

    Wenn Widgets in einem anderen Widget angeordnet werden, wird automatisch eine Eltern<->Kind Verbindung erzuegt. Du kannst dir das auch als einen Baum vorstellen, die Wurzel ist das Fenster und darunter sind alle Widgets die da in welcher Form auch immer reingeschachtelt werden.
    Wenn das Hauptfenster beendet wird erzeugt Qt automatisch ein delete Signal das dann durch den ganzen "Baum" propagiert wird und somit alles sauber abräumt.
     
  7. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Danke, pinky, das war eine sehr verstaendliche Erklaerung. Wenn Qt die delete-Kaskade selber automatisch vornimmt, bedeutet das aber auch, dass es sogar gefaehrlich ist, selber ein Widget, dass man mit 'new' angelegt hat, mit delete wieder freizugeben, da es sonst zu einem 2fachen delete kommen kann?

    Ist das irgendwo dokumentiert? Ich gebe zu, dass ich nicht die ganze Qt-Dokumentation durchgelesen habe, v.a. die einleitenden Kapitel nicht...

    @hehejo
    Ich muss mich der Kritik von slash-ex anschliessen, ob man nun auf einem sauberen OS arbeitet oder nicht: Wenn ich einen Rechner ein Jahr oder mehr laufen habe, auf dem z.B. KDE Kindprozesse oeffnet, die aehnlich lange laufen, wuerde es sehr schnell zu einem vollen Speicher kommen, wenn erst bei beenden des Hauptprogrammes der Speicher wieder freigegeben wuerde. Jedes 'save as' Fenster vom konqueror oeffnet mit Sicherheit so einige Widgets, die dann alle im Speicher rumhaengen wuerden,solange Konqueror noch laeuft. Nach Erklaerung von pinky wird das jedoch von Qt abgefangen.
     
  8. #7 slash-ex, 18.01.2007
    slash-ex

    slash-ex Doppel-As

    Dabei seit:
    04.10.2006
    Beiträge:
    130
    Zustimmungen:
    0
    nicht von qt an sich. die widgets sind alle als "ordentliche" klassen mit nem destruktor geschrieben. bei beenden wirde das widget also delete-d.

    wenn man nun mit vererbt, bekommt die tochterklasse den destruktor mit in die wiege. mehr ist das nicht.

    wenn das widget also die ganze zeit benötigt wird isses egal. muss es evtl. neu erzeugt werden bleiben mit new jedesmal allokierter speicher zurück. das nutze ich manchmal um zeiger auf objekte zu erzeugen um zw. klassen zu kommunizieren^^ gibts da bessere mögl.?

    2. problem: wird eine klasse selber geschrieben und eingebunden. dann kümmert sich "qt" nicht drum und es bleibt auch speicher zurück! grund sollte klar sein.

    und dann ist es noch so ne sache mit der theorie und der praxis... wird das komplette chield oder nur teile aus dem speicher entfernt. könnte mal jemand einen test machen?
     
  9. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Bist Du sicher, dass Du da nicht etwas verwechselst? Wenn man innerhalb eines scopes (einer Funktion, einem Block) mit 'new' etwas erstellt, sei es ein Typ oder eine Klasse, dann wird dieses Objekt nicht automatisch freigegeben, wenn der Block oder die Funktion beendet wird. Man muss irgendwo explizit delete ausfuehren. Ein Beispiel:
    Code:
    class B {
        private:
            int b;
        public:
            B(int y): b(y){}
            ~B(){}
    };
    
    class Foo{
        private:
            B* b;
        public:
            Foo(int m){ b = new B(m); }
            ~Foo(){ }
    };
    
    
    int main()
    {
        Foo* f;
    
        f = new Foo(3);
        delete f;
        return 0;
    }
    
    Wenn ich dieses Programm laufen lasse und mit valgrind starte, bekomme ich die Meldung, dass ich 4 bytes verloren habe, naemlich b;
    Wenn ich in den Destruktor von Foo ein 'delete b' reinschreibe, verschwindet genau diese Meldung, was ich auch erwarte.

    Bei dem Qt-Beispiel, das ich angegeben habe, vermisse ich eben dieses delete. Mehr noch, in den Funktionen werden new's benutzt. Wenn ich die alle im destruktor sauber loeschen will, wird das Programm sehr, sehr schwer pflegbar, und das widerspricht genau der Philosophie von C++.

    Falls es so einen Mechanismus wie pinky ihn angesprochen hat, gibt, dann ergibt sich das ganze Problem natuerlich, weil dann mein Beispielprogramm nicht auf Qt uebertragbar ist. Dazu haette ich gerne eine Referenz.

    Oder uebersehe ich noch etwas Wichtiges?
     
  10. #9 Hello World, 19.01.2007
    Hello World

    Hello World Routinier

    Dabei seit:
    22.11.2006
    Beiträge:
    324
    Zustimmungen:
    0
    In der Trolltech-Dokumentation findet man das in wenigen Minuten.
    http://doc.trolltech.com/4.2/qwidget.html#QWidget
    Außerdem:
    http://doc.trolltech.com/4.2/qwidget.html#dtor.QWidget
    Man kann übrigens auch einen auto_ptr verwenden um sich das lästige deleten zu sparen.
    sbrk() wurde mittlerweile aus POSIX entfernt und in der SUS als deprecated markiert.
     
  11. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Das ist schon alles richtig. Allerdings werden in dem Beispiel, das ich anfangs nannte, eine Menge Widgets ohne 'parent' erzeugt. Sie erscheinen zwar innerhalb des Hauptfensters, und man koennte meinen, dass z.B. die QGroupBox dafuer sorgt, alles sauber aufzuraeumen.
    Wenn ich das Beispiel jedoch per cut-and-paste erstelle und mit valgrind druebergehen, bekomme ich etwa 500000 fehlende Bytes, und das ist ja wohl kein gutes Zeichen!
     
  12. #11 slash-ex, 19.01.2007
    slash-ex

    slash-ex Doppel-As

    Dabei seit:
    04.10.2006
    Beiträge:
    130
    Zustimmungen:
    0
    damit wärs dann geklärt, thx
     
  13. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Tut mir leid, wenn ich mich dumm anstelle, aber fuer mich ist noch nichts geklaert. Ich weiss immer noch nicht, wie man unter Qt korrekt mit Speicherallokation umgeht. Und da KDE auf Qt aufbaut, gehe ich mal davon aus, dass es schon einen Weg gibt, den Speicher auch korrekt wieder freizugeben.
     
  14. #13 Hello World, 19.01.2007
    Hello World

    Hello World Routinier

    Dabei seit:
    22.11.2006
    Beiträge:
    324
    Zustimmungen:
    0
    So wie in jedem anderen C++-Programm auch, von der oben erklärten Ausnahme abgesehen! Und wenn im o. g. Beispiel Speicher verloren geht, dann ist es eben schlecht programmiert. Was gibt es da jetzt nicht zu verstehen?
     
  15. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  16. #14 slash-ex, 19.01.2007
    slash-ex

    slash-ex Doppel-As

    Dabei seit:
    04.10.2006
    Beiträge:
    130
    Zustimmungen:
    0
    wenn ihr einfach nach einem new das objekt auch wieder deleted ist alles in ordnung^^

    aus diesem grund sollte jeder, niemals auf ein delete verzichten.
     
  17. #15 Hello World, 19.01.2007
    Hello World

    Hello World Routinier

    Dabei seit:
    22.11.2006
    Beiträge:
    324
    Zustimmungen:
    0
    Aua... Du weißt aber schon, was passiert, wenn man ein Objekt zweimal deleted?
     
Thema: Programmieren mit qt: new vs. delete
Besucher kamen mit folgenden Suchen
  1. Qt alle mit new erzeugten objekte löschen ?

Die Seite wird geladen...

Programmieren mit qt: new vs. delete - Ähnliche Themen

  1. Kinderleicht: Roboter programmieren mit Open Roberta

    Kinderleicht: Roboter programmieren mit Open Roberta: Das Fraunhofer-Institut für Intelligente Analyse- und Informationssysteme (IAIS), Google und Lego haben das Programm »Open Roberta« gestartet....
  2. PyQT: Wie programmieren?

    PyQT: Wie programmieren?: Hallo, ich weis nicht, ob dieser Beitrag doppelt gepostet wurde, aber es gab da einen kleinen Fehler mit Tapatalk. Ich bin jetzt neu in Python...
  3. PyQT: Wie programmieren?

    PyQT: Wie programmieren?: Hallo, mit welchen Programm schreibe ich am besten in PyQT? Danke im Vorraus Lexi Sent from my iPad using Tapatalk - now Free
  4. Wer hat lust dieses App von Win in Linux zu Programmieren 256kb

    Wer hat lust dieses App von Win in Linux zu Programmieren 256kb: Hi zusammen, wäre es möglich das schnell mal in ein Debian Programm zu schreiben, ich habe keine ahnung vom Programmieren, ich benutze es schon...
  5. Grundlagen Websites programmieren

    Grundlagen Websites programmieren: Hi, ich hab vor längerer Zeit mal Angefangen mir ne Website zu programmieren, damals nur mit html und css. Hat zwar funktioniert, war aber...