Moje pytanie odnosi się do pojęcia "miejscowej wersji new" (placement new).
Przedstawię to na rysunku (adresy pamięci oczywiście ustawione specjalnie w tej kolejności): http://i.imgur.com/AgPJgBU.png
Na początku alokuje dynamicznie pamięć dla pierwszego wskaźnika: int *wsk = new int[10];
Następnie alokuje dynamicznie pamięć dla drugiego wskaźnika: int *wsk_2 = new int[10];
"Szczęście" tak chciało, że obszary pamięci ustawiły się jeden za drugim.
Następnie korzystam z miejscowej wersji new dla trzeciego wskaźnika, wskazując obszar pamięci wskaźnika wsk: int *new_wsk = new (wsk) int[11];
Okazuje się, że 11 element wskaźnika new_wsk[10], czyli ten ostatni, wskazuje na obszar pamięci wskaźnika wsk_2. W moim rozumieniu nadpisuje go.
Pytanie więc: Czy tak właśnie poprawnie działa miejscowa wersja new i to do programisty należy obowiązek dopilnowania, aby obszary pamięci się nie nadpisały? Czy może jest sposób, aby gdy dochodzi do sytuacji jak w wyżej opisanej, aby wskaźnik new_wsk zaalokował pamięć w nowym miejscu za pomocą wbudowanej funkcji w standard języka C++ zamiast nadpisywać inny obszar pamięci? Moim pomysłem byłoby porównywanie adresów pamięci i gdyby okazało się, że są identyczne to użyłbym wtedy zwykłego new zamiast miejscowego. Jeszcze inny pomysł to może inteligentne wskaźniki (smart pointers) są lepiej przystosowane do takich zachowań?
Taki krótki kod w C++, w którym jeden wskaźnik nadpisuje drugi:
#include <iostream>
#include <new>
#include <fstream>
using namespace std;
int main()
{
ofstream plik_wypis_adresow;
plik_wypis_adresow.open("adresy.txt");
int *wsk = new int[10];
int *wsk_2 = new int[10];
plik_wypis_adresow << "Pamiec wsk: " << '\n';
for (int i = 0; i < 10; ++i)
plik_wypis_adresow << &wsk[i] << endl;
plik_wypis_adresow << "\nPamiec wsk_2: " << '\n';
for (int i = 0; i < 10; ++i)
plik_wypis_adresow << &wsk_2[i] << endl;
int *new_wsk = new (wsk) int[11750]; //miejscowa wersja new i nadpisanie pamieci
plik_wypis_adresow << "\nPamiec new_wsk: " << '\n';
for (int i = 0; i < 11750; ++i)
plik_wypis_adresow << &new_wsk[i] << endl;
plik_wypis_adresow.close();
delete[] wsk_2;
delete[] new_wsk; //nie musimy czyscic pamieci wskaznika wsk, robi to new_wsk
}
W moim przypadku nadpisywanie pamięci zachodzi w tym przypadku po zaalokowaniu pamięci dla 11750 zmiennych typu int.