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.


Log in to reply