In C++ wordt geheugentoegang geregeld met expliciete operators new en delete, die geheugen dynamisch toewijzen en vrijgeven. Bij handmatige beheersing is het echter gemakkelijk om geheugenlekken of dubbele vrijgaven te veroorzaken.
Met de introductie van de C++11-standaard zijn slimme pointers geïntroduceerd, zoals std::unique_ptr, std::shared_ptr, std::weak_ptr. Zij beheren automatisch de levenscyclus van objecten en waarborgen dat middelen worden vrijgegeven wanneer ze buiten de scope vallen, zelfs als er een uitzondering optreedt.
Vergelijkingsvoorbeeld:
// Handmatige geheugen vrijgave Foo* ptr = new Foo(); // ... delete ptr; // Veiliger met een slimme pointer std::unique_ptr<Foo> ptr2 = std::make_unique<Foo>(); // delete is niet nodig - alles wordt voor je gedaan door unique_ptr
Slimme pointers verminderen het risico op geheugenlekken en maken de code veiliger en leesbaarder.
Wat gebeurt er als je delete twee keer voor dezelfde pointer aanroept?
Antwoord: Na de eerste aanroep van delete is het geheugen al vrijgegeven. Een tweede aanroep zal leiden tot onbepaald gedrag (undefined behavior). Voorbeeld:
Foo* p = new Foo(); delete p; delete p; // FOUT!
Om dit te voorkomen, stel de pointer in op nullptr na vrijgave:
delete p; p = nullptr;
Verhaal
In een groot C++-project gaf een ontwikkelaar handmatig dynamisch geheugen vrij via
delete, en vergat de pointer te verwijderen bij het verlaten van verschillende takken van de functie met uitzonderingen. Dit leidde tot geheugenlekken die alleen tijdens stress-testing aan het licht kwamen.
Verhaal
Bij het proberen om ruwe pointers te delen tussen verschillende delen van de code, trad een dubbele opschoning van het geheugen op - een van de codeonderdelen voerde
deleteuit zonder de anderen te informeren. Resultaat: segfault in productie, analyse van core dump toonde de oorzaak onmiddellijk aan.
Verhaal
Na de migratie van een oud project naar nieuwe C++-standaarden werd een deel van de code met ruwe pointers achtergelaten, terwijl nieuwe klassen al werkten met slimme pointers. Problemen met het overdragen van eigendom van middelen deden zich voor: het geheugen werd 'tweemaal' vrijgegeven - eerst handmatig, vervolgens automatisch door de destructors van de slimme pointers.