Za pomocą operatora new można przydzielić pamięc o z góry określonej lokalizacji. Istnieje do tego celu specjalna forma operatora new — dostępna po dołączeniu pliku nagłówkowego new — o następującej składni:
new (adres) Typ; new (adres) Typ[wymiar];W ten sposób przydzielamy na pojedynczy obiekt lub tablicę obszar pamięci rozpoczynający się od adresu będącego wartością wyrażenia adres. W zasadzie obszar ten powinien mieścić się w jakimś obszarze pamięci przydzielonym wcześniej za pomocą „zwykłego” new. Jest to operacja szybka, ponieważ tak naprawdę nie wymaga alokowania pamięci; kompilator zakłada, że programista wie co robi. Ponieważ tak naprawdę przydziału pamięci nie ma, obszar ten powinien zostać zwolniony przez wywołanie delete ze wskaźnikiem takiego typu i zawierającym ten adres, który był użyty w „prawdziwym” new, a nie w new lokalizującym!
W poniższym przykładzie alokujemy (➊) tablicę
arr
znaków
(czyli bajtów) o wymiarze pozwalającym pomieścić tam trzy
sz-elementowe tablice różnych typów(string,
double
i
int). Wewnątrz obszaru pamięci przez nią
zajmowanego „alokujemy” trzy osobne tablice, obliczając za każdym
razem (patrz na przykład ➋) pod jakim adresem powinny się
rozpoczynać, aby pomieścić się w dostępnej pamięci:
1. #include <iostream> 2. #include <string> 3. 4. int main() { 5. using std::string; using std::cout; using std::endl; 6. int sz = 3; 7. 8. char* arr = new char[sz*(sizeof(string) + ➊ 9. sizeof(double)+sizeof(int))]; 10. 11. string* nam = new (arr) string[sz]{"Sue", "Kim", "Joe"}; 12. double* wei = new (arr+sz*sizeof(string)) ➋ 13. double[sz]{55.5, 61.2, 81.5}; 14. int* hei = new (arr+sz*(sizeof(string)+sizeof(double))) 15. int[sz]{170, 165, 183}; 16. for (int i = 0; i < sz; ++i) 17. cout << nam[i] << " " << wei[i] << " " 18. << hei[i] << endl; 19. delete [] arr; ➌ 20. }
Wydruk
Sue 55.5 170 Kim 61.2 165 Joe 81.5 183świadczy o tym, że tablice zostały prawidłowo zaalokowane i zainicjowane. Pamiętamy oczywiście, aby zwalniając pamięć (➌) użyć adresu otrzymanego przez „prawdziwe” new!
Opisany rodzaj przydzielania pamięci stosuje się też często aby wykorzystać na nowe dane wcześniej zaalokowane, a zawierające dane już niepotrzebne, obszary pamięci — jest to znacznie szybsze niż zwalnianie i potem przydzielanie pamięci od nowa.
T.R. Werner, 23 lutego 2022; 19:40