Was passiert, wenn ich Speicher nicht freigebe?



  • CStoll schrieb:

    ne0r schrieb:

    Naja, das +1 macht da schon Sinn und dass die Array-Größe variabel ist, das hab ich mir schon überlegt 😉

    Ja, die +1 muß sein, aber sie gehört VOR die schließende Klammer ].

    Ups, stimmt!
    😉



  • Artchi schrieb:

    ne0r! Die Frage ist eher, warum man einen nackten C-String zurück geben sollte? Wenn man was mit C-Strings machen will/muß, dann würde ich doch eher einen initialisierten char-Pointer als Parameter haben wollen:

    void return_a_cstring(char *str, std::size_t length);
    

    Dein Beispiel würde ich eher unter "schlechtes Design" einordnen.
    Und wenn ich C++ mache, würde ich dann sogar eher einen std::string oder std::wstring zurück geben. Dann muß sich niemand um die Freigabe kümmern. Oder einen Smartpoint std::auto_ptrstd::string.

    std::auto_ptr<std::string> return_a_string()
    {
        std::auto_ptr<std::string> str(new std::string());
        /* irgendwas in str schreiben */
        return str;
    }
    

    Nur eine Bemerkung/Frage am Rande: Da verlaesst du dich aber auch darauf, dass dein Compiler eine NRV Optimierung beherrscht, oder seh ich das falsch? Denn sonst koennte der Compiler ja (und AFAIK waere das auch voellig legal) den Destruktor von str gleich am Ende der Funktion aufrufen, und damit waere auch dein String futsch 😕 Schreibst du also ernsthaft solchen Code oder war das nur ein Fluechtigkeitsfehler?



  • Um ganz ehrlich zu sein, weiß ich nicht, was du meinst? 😕 Was soll NRV sein? Ich denke bei dem Konstrukt an gar keine Optimierung sondern daran, was logisch passiert. Aber ich weiß nicht worauf du hinaus willst.



  • Artchi schrieb:

    Um ganz ehrlich zu sein, weiß ich nicht, was du meinst? 😕 Was soll NRV sein? Ich denke bei dem Konstrukt an gar keine Optimierung sondern daran, was logisch passiert. Aber ich weiß nicht worauf du hinaus willst.

    NRV: Named Return Value Optimization
    http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Optimize#Answ

    Ich will auf folgendes hinaus:
    Du erstellst in der Funktion einen LOKALEN auto_ptr. Beim Verlassen der Funktion wird dieser auto_ptr deshalb (zumindest ohne NRVO) geloescht, und beim Loeschen wird ja dann auch der Dtor von auto_ptr aufgerufen. Und dabei wird dann ja auch dein String wieder geloescht. Oder?



  • Nee. So wie es im Code steht, wird eine Kopie des lokalen auto_ptr zurueckgegeben und keine "weak reference".



  • Achso... das meinst du. Ehm, also die Semantik des auto_ptr ist ja, das er das Objekt unversehrt weitergibt. Ist eigentlich der Sinn von dem Ding. Deshalb benutze ich ihn gerne, wo er für mich sinnvoll erscheint. Kannst du aber auch selber ausprobieren. Hab mal ein kleines Testprogramm geschrieben:

    #include <memory>
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    public:
       Test(){ cout << "Ctor" << endl; }
       ~Test(){ cout << "Dtor" << endl; }
    };
    
    auto_ptr<Test> ret()
    {
    	auto_ptr<Test> str(new Test());
    	return str;
    }
    
    int main()
    {
       auto_ptr<Test> t = ret();
       cout << "Vor main()-Ende" << endl;
    }
    

    Ergebnis:

    Ctor
    Vor main()-Ende
    Dtor
    

    Also, alles in Butter.



  • Naja. So einfach ist das nicht. Die lokale Variable liegt auf dem Stack und beim Verlassen der Funktion wird der Stackpointer einfach dekrementiert. Die Daten sind aber nach wie vor da und gueltig. Das Problem tritt erst ein, wenn neue Daten auf den Stack gelegt werden und die alten ueberschrieben werden. Dann ist deine Referenz auf ein Objekt, welches auf dem Stack liegt (lag) nichts mehr wert. Aber so wie es im Code steht gibst Du ja eine Kopie zurueck. Daher ist wirklich alles in Butter 😉



  • rüdiger schrieb:

    thordk schrieb:

    "Was passiert, wenn ich Speicher nicht freigebe?"

    nichts. du ballerst nur dem ram voll und bekommst den nicht mehr leer, ohne dein programm zu beenden.

    Und es werden keine Destruktoren aufgerufen, was zu deutlich unangenehmeren Folgen führen kann.

    aber nur, wenn man irgendwelchen schweinkrams baut, der mit nicht reserviertem speicher rumhantiert. was auf ca. 0.1% der hier awesenden zutreffen dürfte, wobei auch nur 5% davon wissen, warum sie das machen.



  • Artchi schrieb:

    Achso... das meinst du. Ehm, also die Semantik des auto_ptr ist ja, das er das Objekt unversehrt weitergibt. Ist eigentlich der Sinn von dem Ding. Deshalb benutze ich ihn gerne, wo er für mich sinnvoll erscheint.

    D.h. beim Kopieren vom auto_ptr verliert der Urspungs-auto_ptr die Verantwortung fuer den Pointer? *versteh*



  • Blue-Tiger schrieb:

    Artchi schrieb:

    Achso... das meinst du. Ehm, also die Semantik des auto_ptr ist ja, das er das Objekt unversehrt weitergibt. Ist eigentlich der Sinn von dem Ding. Deshalb benutze ich ihn gerne, wo er für mich sinnvoll erscheint.

    D.h. beim Kopieren vom auto_ptr verliert der Urspungs-auto_ptr die Verantwortung fuer den Pointer? *versteh*

    Nicht nur die Verantwortung, der Urspungs-auto_ptr ist nachher 0 (leer).



  • Yo, "es kann nur einen geben!" 😃

    auto_ptr<string> a(new string("Hallo!"));
    cout << "a zeigt auf: " << a.get() << endl;
    
    auto_ptr<string> b = a;
    
    cout << "a zeigt auf: " << a.get() << endl;
    cout << "b zeigt auf: " << b.get() << endl;
    

    Ergebnis:

    a zeigt auf: 003212A8
    a zeigt auf: 00000000
    b zeigt auf: 003212A8
    

    auto_ptr ist somit sehr speziell, aber es funktioniert, wenn man dieses Verhalten haben will.



  • thordk schrieb:

    rüdiger schrieb:

    thordk schrieb:

    "Was passiert, wenn ich Speicher nicht freigebe?"

    nichts. du ballerst nur dem ram voll und bekommst den nicht mehr leer, ohne dein programm zu beenden.

    Und es werden keine Destruktoren aufgerufen, was zu deutlich unangenehmeren Folgen führen kann.

    aber nur, wenn man irgendwelchen schweinkrams baut, der mit nicht reserviertem speicher rumhantiert. was auf ca. 0.1% der hier awesenden zutreffen dürfte, wobei auch nur 5% davon wissen, warum sie das machen.

    nö. destruktoren können auch andere resourcen freigeben.


Anmelden zum Antworten