Rezerwacja obszarów pamięci to kolejne pole zastosowania wskaźników. Z tą problematyką wiąże się również wykorzystanie operatorów new oraz delete. Robią one to samo, co funkcje malloc i free znane z klasycznego języka C. Ich działanie omówione jest zresztą w części dotyczącej języka C poświęconej dynamicznej alokacji pamięci. Częste wykorzystanie tych funkcji w C, doprowadziło do implementacji w standardzie C++ nowych operatorów (new i delete) odpowiedzialnych za rezerwację obszarów pamięci. Trzeba przyznać, że w języku C++ obiekty dynamiczne są tworzone lepiej i łatwiej.
Nowy obiekt tworzymy operatorem new, natomiast niszczymy go operatorem delete. Operator delete nic nie zwraca (void), a stosujemy go tylko do obiektów utworzonych operatorem new. Spójrzmy na program newdel.cpp. Deklarujemy w nim trzy wskaźniki do obiektów całkowitych, natomiast nie ma tam żadnych "zwykłych" zmiennych. Instrukcja tworząca nowy obiekt ma postać:
a = new int;Nie ma on nazwy, lecz jego adres przekazywany jest wskaźnikowi a. Można również utworzyć nowy obiekt w zapasie pamięci i od razu wpisać do niego jakąś wartość. Ilustruje to następująca instrukcja w kodzie programu:
b = new int(20);Jest ona równoważna zapisowi:
b = new int; *b = 20;
Bardzo interesująco dla reszty działań przedstawia się linijka przypisująca wskaźnikowi a adres obiektu wskazywanego przez wskaźnik b. Od tej chwili tracimy adres obiektu, na który a wskazywał pierwotnie. Nie jest już możliwa modyfikacja czy odczyt jego wartości. Oba wskaźniki identyfikują teraz ten sam obszar pamięci. Zmiany (lub odczytu) wartości tego obiektu możemy teraz dokonać, albo poprzez wskaźnik a, albo poprzez wskaźnik b. Uwaga również usunięcia tego obiektu możemy dokonać na dwa sposoby:
delete a;lub
delete b;Błędem byłoby, gdybyśmy zapisali tutaj taki oto fragment kodu:
delete a; delete b;Pierwsza instrukcja skasowałaby obiekt, na który wskazuje wskaźnik a, druga usunęłaby... No właśnie, nie wiemy, co zostałoby usunięte, od kiedy wskaźnik b pokazuje na ten sam obiekt, co wskaźnik a. Dwukrotne kasowanie tego samego obiektu może doprowadzić do tragedii. Wyjściem z sytuacji jest ustawienie obu wskaźników na NULL, tak jak w poniższym kodzie:
delete a; a = NULL; b = NULL; delete a; // OK delete b; // OKNie będzie nieszczęścia, jeżeli zastosujemy operator delete w stosunku do wskaźników pokazujących na adres zerowy, czyli właśnie wskaźników NULL (żaden obiekt nie może mieć adresu zero).
Na koniec jeszcze słówko o tworzeniu tablic. Prześledźmy kod źródłowy programu dyntab.cpp. Jest tam pokazana dynamiczna alokacja tablicy. Dzięki użyciu operatora new rozmiar tablicy nie musi być stałą. W naszym przypadku rozmiar tablicy tab zawierającej elementy całkowite, ustalany jest w trakcie działania programu i zależy od użytkownika. Należy pamiętać, że jeśli ustalimy liczbę elementów na przykładowo 6, a później zechcemy odczytać element 7 lub co gorsza wpisać coś do niego, skutki mogą być katastrofalne. W programie zaimplementowano proste sprawdzanie poprawności operacji tworzenia nowego obiektu w dostępnym zapasie pamięci. Zamiennie zostały użyte notacje wskaźnikowe i tablicowe. Usuwanie tablicy pod koniec programu przyjmuje formę:
delete [] tab;