ProgrammatieC++ ontwikkelaar

Wat is 'placement new' in C++? Voor wat en hoe wordt dit mechanisme gebruikt?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

placement new is een speciale vorm van de new operator in C++. Het stelt je in staat om een object op een specifieke locatie in al toegewezen geheugen te plaatsen. Het wordt meestal gebruikt voor handmatig geheugenbeheer, vormt de basis voor allocators, object pooling en serialisatie naar vaste bufffers.

Syntax:

#include <new> void* memory = malloc(sizeof(MyClass)); MyClass* obj = new (memory) MyClass(args...); // roept de constructor aan op het adres memory

Hier wordt het geheugen apart toegewezen (bijvoorbeeld via malloc of een allocator), en vervolgens wordt de constructor van de klasse op dat geheugen aangeroepen. Vergeet niet om de destructor expliciet aan te roepen:

obj->~MyClass(); free(memory);

Voordelen:

  • Maakt het mogelijk om eigen allocators te implementeren.
  • Vermindert de kosten van nieuwe geheugenallocatie.
  • Roept de standaardallocator niet aan — controle over geheugenbeheer.

Aanknopingsvraag

Kan hetzelfde geheugenblok worden gebruikt om meerdere objecten achtereenvolgens te plaatsen met 'placement new', en welke gevolgen heeft dit?

Een veelvoorkomend verkeerd antwoord is dat je nieuwe objecten in het geheugen kunt plaatsen zonder je zorgen te maken over de vorige staat. In werkelijkheid, als je een nieuw object bovenop een oud object in hetzelfde geheugen plaatst zonder de destructor aan te roepen, leidt dit tot resource-lekken, en het aanroepen van de destructor leidt dan tot UB.

Voorbeeld:

void* place = malloc(sizeof(A)); A* a = new (place) A(); B* b = new (place) B(); // object A is niet vernietigd! UB!

Voorbeelden van echte fouten door gebrek aan kennis van de fijne kneepjes van het onderwerp


Verhaal

In een hoogbelaste systeem heeft de ontwikkelaar een objectpool geïmplementeerd via malloc + placement new, maar vergat de destructor aan te roepen bij het retourneren van een object naar de pool. Uiteindelijk werden de resources (systeem descriptors binnen objecten) niet vrijgegeven, wat leidde tot lekken en 'bevriezing' van servers.



Verhaal

In een project voor het serialiseren van binaire data werd een buffer en placement new gebruikt om objecten ter plaatse te decoderen. Echter werd vergeten om het geheugen op nul te initialiseren voordat het werd geplaatst, wat leidde tot het lezen van niet-geïnitieerde gegevens en vreemde bugs bij het werken met POD-structuren.



Verhaal

Een van de modules migreerde naar het plaatsen van arrays van objecten met behulp van placement new binnen een vooraf toegewezen blok. Na het toevoegen van nieuwe leden met niet-triviale destructors binnen de klasse, ontstonden er programma-crashes — vergeten dat de destructor nu expliciet voor elk element moet worden aangeroepen bij het opruimen, wat eerder niet nodig was.