New in Try Block



  • Konnte dem Benutzernamen nicht wiederstehen 🙂

    Meine Frage an die Profis hier :

    Bspl.:

    int X = 5;
    double *ptr;
    
    try{
    
        ptr = new double[X]
    }catch(std::exception &e){
          std::cout << "\n" e.what();
    }
    
    ptr[3] = 2.2;
    
    //.....
    
    delete [] ptr;
    

    Ist der Reservierte Speicher mit new außerhalb des Try Blocks gültig ? Normal wird doch alles was in dem Try Block definiert wird, beim Verlassen zerstört?

    => Ich weiß man soll keine Raw New´s benutzen. Darum geht es mir aber jetzt nicht.



  • fat&ugly_girl schrieb:

    Ist der Reservierte Speicher mit new außerhalb des Try Blocks gültig ?

    Hängt davon ab, ob er im Try-Block erzeugt wurde oder nicht...

    fat&ugly_girl schrieb:

    Normal wird doch alles was in dem Try Block definiert wird, beim Verlassen zerstört?

    In dem Block wird aber nichts definiert. Die Definition ( double *ptr; ) steht vor dem Try-Block... 😉



  • fat&ugly_girl schrieb:

    Ist der Reservierte Speicher mit new außerhalb des Try Blocks gültig ?

    Ja.

    Normal wird doch alles was in dem Try Block definiert wird, beim Verlassen zerstört?

    Für try-Blöcke gibt es in Bezug darauf keine Sonderregeln, es passiert genau das gleiche wie bei allen anderen Blöcken auch. Da bei dir keine Variablen definiert werden, gibt es auch nichts zum zerstören.


  • Mod

    fat&ugly_girl schrieb:

    Ist der Reservierte Speicher mit new außerhalb des Try Blocks gültig ?

    Ja, sofern er reserviert wurde (und nicht später wieder freigegeben). Wurde allerdings eine Exception beim new geworfen, wurde dem Zeiger nie ein Wert zu gewiesen, dieser ist dann folglich immer noch unbestimmt.



  • Wurde allerdings eine Exception beim new geworfen, wurde dem Zeiger nie ein Wert zu gewiesen, dieser ist dann folglich immer noch unbestimmt.
    

    Hmm... da ich die Exception fange müsste ich dann den Zugriff auf den ptr irgendwie verhindern. Das wird dann wohl nur über Smart-Pointer lösbar sein ?



  • Die erste Frage sollte sein: Wieso willst du überhaupt außerhalb vom Try-Block was mit dem Pointer anstellen?



  • einfach die funktion verlassen nachdem die fehlermeldung ausgeben wurde? schließlich kannst die funktion dann eh nix sinnvolles mehr machen...



  • fat&ugly_girl schrieb:

    Wurde allerdings eine Exception beim new geworfen, wurde dem Zeiger nie ein Wert zu gewiesen, dieser ist dann folglich immer noch unbestimmt.
    

    Hmm... da ich die Exception fange müsste ich dann den Zugriff auf den ptr irgendwie verhindern. Das wird dann wohl nur über Smart-Pointer lösbar sein ?

    Nein ... nicht nur. Du kannst ja bei der Deklaration des Pointers den Zeiger direkt mit nullptr initialisieren.

    double *ptr = nullptr;
    

    Wenn dann kein Speicher mit "new" reserviert werden kann und dem Zeiger dann keine Speicheradresse zugewiesen werden kann, kannst du den Pointer ja noch immer vor Benutzung auf != nullptr überprüfen.
    Wenn dann gilt (ptr == nullptr) weisst du, dass du keinen Speicher reservieren konntest.



  • nullptr schrieb:

    Wenn dann kein Speicher mit "new" reserviert werden kann und dem Zeiger dann keine Speicheradresse zugewiesen werden kann, kannst du den Pointer ja noch immer vor Benutzung auf != nullptr überprüfen.
    Wenn dann gilt (ptr == nullptr) weisst du, dass du keinen Speicher reservieren konntest.

    und dann? dann kann er wenn (ptr == nullptr) die funktion verlassen. kann er aber auch gleich im catch block, ist also ziemlich sinnlos und redundant.



  • Und sämtliche Probleme lösen sich in Luft auf, wenn man Smart-Pointer benutzt.

    Das einzige, was noch passieren kann ist, dass new wirft und da tritt noch kein Memory Leak auf. Also kein Problem...



  • Skym0sh0 schrieb:

    Und sämtliche Probleme lösen sich in Luft auf, wenn man Smart-Pointer benutzt.

    nö, eigentlich nicht. darum gehts hier nämlich gar nicht:

    #include <iostream>
    #include <exception>
    #include <memory>
    
    int main() {
    	std::unique_ptr<int> ptr;
    	try {
    		ptr = std::make_unique<int>();
    	}
    	catch (std::exception const &ex) {
    		std::cerr << ex.what() << '\n';
    	}
    	*ptr = 5; // Und jetzt?
    	std::cout << *ptr << '\n';
    }
    

    problem ist und bleibt dass man wenn das alloc von ptr fehlschlägt auch mit einem smartpointer nix mehr anfangen kann (der zeigt schließlich auf nix sinnvolles) -> funktion im catch-block (nach fehler-ausgaben) verlassen


  • Mod

    try_catch schrieb:

    funktion im catch-block (nach fehler-ausgaben) verlassen

    Oder wesentlich sinnvoller: sämtlichen Code, der von einer exceptionfreien Ausführung abhängt, in den try-Block verlagern. Andernfalls wäre der Code mit einem nothrow-new besser strukturiert.



  • oder noch besser: exceptions die man nicht sinnvoll behandeln kann gar nicht erst seperat fangen. fürs fehlermelden reicht ein einziger try-catch block in der main, ansonsten macht es relativ wenig sinn nach einer exception so zu tun als wär nix passiert (wie in dem gezeigten code)



  • ptr = std::make_unique<int>();
    

    Wie geht das eigentlich in C++ 11 auf obriges Bspl. angewandt



  • Einfach mit new. Das make_unique hat hier keinerlei Vorteile.


Anmelden zum Antworten