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