Speicherreservierung mit new



  • Hallo

    Garantiert mir der C++-Standard, dass ein Zeiger der auf ein mit new reserviertes Objekt immer ungleich NULL ist?

    MfG, EOutOfResources



  • Ja.



  • Nein.

    #include <iostream>
    
    class MyOb {
    public:
      int i;
      MyOb() : i (200) {}
    };
    
    int main()
    {
        MyOb * meins = new MyOb;
    
        #define NULL meins // dont do this, its UB :(
    
        std::cout << NULL;
    
    }
    

    Deswegen: [c]0[/c] statt [c]NULL[/c]. Zugegebenermassen etwas konstruiert 😉 aber es garantiert dir keiner das [c]NULL == 0[/c], also kann da auch was anderes drinstehen, und wenn das nun zufällig genau das ist was das [c]new[/c] als Adresse erzeugt, PECH.



  • padreigh schrieb:

    [...] aber es garantiert dir keiner das NULL == 0 , also kann da auch was anderes drinstehen, und wenn das nun zufällig genau das ist was das new als Adresse erzeugt, PECH.

    Doch, der Standard garantiert Dir das. Was Du da tust ist produziert UB und ist daher eh nicht relevant für die Frage.

    EOutOfResources schrieb:

    Hallo

    Garantiert mir der C++-Standard, dass ein Zeiger der auf ein mit new reserviertes Objekt immer ungleich NULL ist?

    MfG, EOutOfResources

    Wenn Dein Name Programm wird, dann kann es, je nach Konfiguration der new -Fehlerbahandlung sein, dass new 0 zurückgibt.



  • padreigh schrieb:

    Deswegen: 0 statt NULL .

    Man muss immer Pimpl einsetzen und die Body-Klasse in der .cpp-Datei verstecken. Sonst könnte jemand #define private public schreiben und die Kapselung aufheben.

    So läuft das in C++ nicht. 😉



  • Mist 😉 gibts irgendwo eingentlich eine Liste von UB? Wo schau ich sowas nach?



  • padreigh schrieb:

    Nein.

    #define NULL meins
    

    Ob das erlaubt ist?
    Aber mach doch

    #define new new(badHint)
    

  • Mod

    Thou shalt not redefine reserved identifiers!

    NULL, new, private, usw. zählen alle dazu.

    padreigh schrieb:

    Mist 😉 gibts irgendwo eingentlich eine Liste von UB? Wo schau ich sowas nach?

    Den Standard nach "undefined" durchsuchen? Das lohnt aber den Aufwand nicht, gesunder Menschenverstand und Erfahrung sollten für die meisten Fälle reichen und ansonsten guckt man eben gezielt im Standard. Hier Kapitel 2.10 "Identifiers" wo man schon private und new findet und von dort wird man weiterverwiesen nach 17.4.3.1 "Reserved names" wo dann indirekt NULL ausgeschlossen wird.



  • padreigh schrieb:

    Mist 😉 gibts irgendwo eingentlich eine Liste von UB? Wo schau ich sowas nach?

    Im C++ Standard...



  • Ich komm zwar in dem pdf das ich fand (Dank für den Link) (N3225 10-0215 Working Draft, Standard for Programming Language C++ Pete Becker 2010-11-27 2010-11 N3126=10-0116=) leicht andere Kapitelnummern aber sieht so aus als wär das tatsächlich verboten. Snüff. Wie bekomm ich denn heraus welche Doku "meinem" C++ entspricht? (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5))



  • padreigh schrieb:

    Wie bekomm ich denn heraus welche Doku "meinem" C++ entspricht? (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5))

    Der Sinn eines Standards ist ja gerade, dass es nicht verschiedene Versionen gibt 😉

    Die meisten Compiler haben zwar gewisse Erweiterungen, aber um portabel programmieren zu können, solltest du dich soweit möglich an den C++-Standard halten. Abweichungen findest du in der Dokumentation deines Compilers.



  • padreigh schrieb:

    Wie bekomm ich denn heraus welche Doku "meinem" C++ entspricht? (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5))

    Das ist der C++ Standard (und eben das aktuelle Working Draft für den Neuen und nicht der momentan gültige Standard, darum die etwas anderen Nummern) und keine Doku...



  • Hab ich die Frage falsch verstanden? Hier steht doch ganz klar, dass die Rückgabe von new NULL ist, wenn kein Speicher mehr vorhanden ist und die nothrow-Variante vom Operator new genommen wird:

    http://www.cplusplus.com/reference/std/new/operator%20new/



  • VielleichtFalschversteher schrieb:

    Hab ich die Frage falsch verstanden? Hier steht doch ganz klar, dass die Rückgabe von new NULL ist, wenn kein Speicher mehr vorhanden ist und die nothrow-Variante vom Operator new genommen wird:

    http://www.cplusplus.com/reference/std/new/operator%20new/

    Von nowthrow war hier nie die Rede, es geht um das Verhalten von new. Und da garantiert der Standard, dass man den Speicher bekommt oder eine bad_alloc exception geworfen wird.



  • DocShoe schrieb:

    Von nowthrow war hier nie die Rede, es geht um das Verhalten von new. Und da garantiert der Standard, dass man den Speicher bekommt oder eine bad_alloc exception geworfen wird.

    Es war die Rede vom operator new und der beinhaltet unter anderem die nothrow-Variante. Deswegen kann man doch nicht allgemein sagen, dass der Pointer, der mit new initialisiert wird, niemals NULL ist.



  • Nein, die Frage war

    Garantiert mir der C++-Standard, dass ein Zeiger der auf ein mit new reserviertes Objekt [zeigt] immer ungleich NULL ist?

    Die Reservierung ist aber nicht erfolgt, wenn new wirft.



  • Eisflamme schrieb:

    Die Reservierung ist aber nicht erfolgt, wenn new wirft.

    Genau! Wenn geworfen wird, will ich überhaupt nicht auf Gleichheit mit NULL prüfen.

    Danke!


  • Mod

    EOutOfResources schrieb:

    Hallo

    Garantiert mir der C++-Standard, dass ein Zeiger der auf ein mit new reserviertes Objekt immer ungleich NULL ist?

    MfG, EOutOfResources

    NULL ist nach Konvertierung in einen beliebigen Zeigertyp ein Nullzeiger. Ein Nullzeiger zeigt definitionsgemäß niemals auf irgendein Objekt (ob nun per new oder irgendwie anders erzeugt).
    Im Umkehrschluss folgt, dass wenn new erfolgreich war und ein Objekt erzeugt hat, das Resultat kein Nullzeiger sein kann.



  • Long story short: new wirft eine std::bad_alloc exception wenn das allokieren fehlschlägt. Außer es handelt sich um die nothrow Variante oder es kommt sonstwie ein komisch überladener operator new() ins Spiel. Wenn new wirft brauchst du nichts auf 0 zu prüfen denn soweit kommst du dann sowieso gar nicht...



  • c++ Standard hin oder her, was ist eigentlich mit denen, die ihren Code mit deaktivierten Exceptions bauen müssen - das kenne ich von einigen Projekten für eingebettete Systeme, das erste, was ausgeschaltet wird, ist Exception-Handling. Was macht new in diesem Fall, was garantiert der Standard 😕


Log in to reply