placement new



  • was ist das? dabei darf man den destruktor selbst aufrufen?



  • Placement new hat nichts mit Destruktoraufrufen zu tun. Normalerweise reserviert new Speicher und konstruiert dort das Objekt. Placement new hingegen benutzt bereits vorhandenen Speicher (welcher dabei angegeben werden muss) und konstruiert das Objekt dort. Wenn du mehr darüber erfahren willst, solltest du dir mal den Abschnitt 5.3.4 im Standard näher anschaun.



  • @groovemaster doch man muss den dtor sogar explizit aufrufen, weil das objekt sonst nicht zerstört wird.



  • Hätte vielleicht eher sagen sollen, dass placement new primär erstmal nichts mit Destruktoraufrufen zu tun hat und eher eine Begleiterscheinung darstellt. Sofern sich auf dem Speicher ein ctored Objekt befindet, hast du natürlich Recht, es gibt aber auch Szenarien wo das nicht der Fall ist und wo ein Destruktoraufruf deshalb auch nicht notwendig ist.



  • Wenn der Destruktor trivial ist, muss man ihn auch nicht aufrufen. Triviale Feststellung zwar, aber trotzdem ... 😉



  • ansonsten kann man sich doch ohne Probleme einen kleinen SmartPointer dafür basteln. Weil ich mag Dinge, die sich selbst aufräumen und zerstören. Dann muss ich auch nicht schlecht schlafen, weil ich Angst haben muss, dass in meinem Code zB. eine Exception fliegt.



  • Verstehe nicht, wie man placement new verwendet. Kann bitte jemand ein klares Beispiel zeigen/linken?



  • es geht hauptsächlich darum, dass du in Speicher, den du auf anderem Wege erhälst Objekte erzeugen kannst (zB. Shared Memory).

    Hier mal ein kleines Beispiel

    class foo {
      //...
    };
    
    char buffer[sizeof(foo)];
    foo *ptr=new (buffer) foo(/*Ctor Argumente*/);
    //...
    ptr->~foo();
    

    (wobei ich wie gesagt einen kleinen smart pointer für die Freigabe von ``ptr'' schreiben würde)



  • class foo {
      //...
    };
    
    char buffer[sizeof(foo)];
    foo *ptr=new (buffer) foo(/*Ctor Argumente*/);
    //...
    ptr->~foo();
    

    Hab da ne Frage dazu (gehört ja auch zum Thema).

    Liegt dann also ptr auf dem Stack ?
    Ist dann auch der Zugriff so schnell
    wie normale Zugriffe am Stack ?

    sorry für Zwischenfrage



  • Tankian schrieb:

    char buffer[sizeof(foo)];
    foo *ptr=new (buffer) foo(/*Ctor Argumente*/);
    [/cpp]

    Liegt dann also ptr auf dem Stack ?

    ptr liegt sowieso auf dem Stack. Du meinst das foo-Objekt, dass dort erstellt wird? Ja, das liegt an der gleichen Adresse wie buffer (Achtung: Möglicherweise darf ein foo nur an bestimmten, durch sizeof(foo) teilbaren Adressen liegen (Alignment). Es ist aber nicht garantiert, dass buffer diese Anforderung erfüllt, so dass das Placement new an dieser Stelle undefiniertes Verhalten hat.)

    Ist dann auch der Zugriff so schnell
    wie normale Zugriffe am Stack ?

    Zugriffe auf Stack-Objekte sind eigentlich genauso schnell wie auf Heap-Objekte.

    Das Anlegen der Objekte ist unterschiedlich schnell. Da der Stack immer nur an der Spitze wächst und abgebaut wird, kann dort sehr schnell Speicher bereitgestellt werden. Im Heap (oder Freispeicher) dagegen muss immer erst ein freier Block gesucht werden. Bei Placement new entfällt das Suchen natürlich, weil der Block vom Programmierer angegeben wird.



  • Jo meinte natürlich, das Objekt auf das ptr zeigt.

    Danke für die Erklärung 🙂


Log in to reply