Placement New?



  • seh ich das richtig, das anfangs (A) ein Buffer von 1000 bytes reserviert wird,
    und über placment new (B) ein string mit 2 bytes in den schon reservieren bereich geschrieben wird, so das (B) kein neuen speicher reserviernem muss, und man so sicehr gehen kann das speicehr da ist?

    /*A*/ char *buf  = new char[1000];   //pre-allocated buffer
     /*B*/	string *p = new (buf) string("hi");  //placement new
    

    wenn ich jetzt bspw. eine Klasse

    class foo{
    
    int A;
    char B;
    float C;
    
    };
    

    habe und diese mit placment new anlegen will.. wie geh ich da vor?



  • Placement new nimmt vorhandenen Speicher um Objekte darin zu konstruieren. Das bedeutet das kein weiterer Speicher reserviert werden muss, die Objekte nutzen lediglich den vorhandenen Speicher. Dein Beispiel Konstruiert ein String Objekt in den ersten Bytes deines Puffers, der Rest des Puffers ist in dem Fall einfach ungenutzt.

    Bei deiner Struktur gehst du genauso vor:

    foo* p = new ( buf ) foo;
    

    Da du aber keinen Standardkonstruktor definiert hast werden die Membervariablen nicht initialisiert und der, vom Compiler erzeugte, Standard c'tor verwendet.



  • und wann wird placment new verwendet?

    Um sicher zu gehen das speicher vorhanden ist?
    Und um erhöhte Performance zu ereichen?



  • Wenn du ein Array von nicht konstruierten Elementen haben willst (kann mit unter viel schneller sein). Oder wenn du eine Array von Elementen haben willst und diese Elemente bieten keinen standard c'tor an.

    Versuch mal: 😉

    struct foo
    {
        foo( int x ) {}
    };
    
    int main()
    {
        foo* p = new foo[ 10 ];
    }
    


  • du meinst:

    foo* p = new (buf) foo[ 10 ];
    


  • Nein, ich meine das was ich gepostet habe!



  • achso du dachte du legst mehre instanzen des objekts also das array in den bereits reservieren bereich? aber würde das gehen so wie ich es geschrieben habe?



  • Nein! Eher so:

    // Speicher reservieren
    char* buff = ( char* ) ::operator new( 10*sizeof( foo ) );
    foo* my_array[ 10 ];
    
    // Konstruieren mit foo::foo( int )
    for ( int i = 0; i < 10; ++i )
    {
    	my_array[ i ] = new ( buff+sizeof( foo )*i ) foo( i );
    }
    
    // Zerstören
    for ( int i = 0; i < 10; ++i )
    {
    	my_array[ i ]->~foo();
    }
    
    // Speicher freigeben!
    ::operator delete( buff );
    


  • verwenden kannst du das beim eigenen speichermanagement (wenn z.b. du immer pools haben willst). manche objekte regestrieren sich im c-tor irgendwo, das moechtest du vielleicht garnicht, aber du willst den pool schon haben also
    new char[sizeof(CMyClass)*POOLSIZE];
    und dann bei jeder instanzierung den inplacement new. manchmal hast du auch keinen default c-tor, willst aber den speicher im voraus anlegen weil du weisst dass du gleich z.b 1mio objekte generieren wirst.
    manchmal haben die objekte auch ne dynamische groesse z.b.

    class foo
    {
    privat:
      int  m_Size;
      char m_ObjList[1];
    public:
           foo(int Size):m_Size(Size){}
    };
    //on alloc
    pData = new char[sizeof(foo)+ObjCount];
    new (pData) foo(ObjCount);
    

    so sparst du dir den overhead vom zusaetzlichen new in foo und den pointer auf eine ObjList.

    gibt grenzenlose moeglichkeiten 🙂


Anmelden zum Antworten