Witam, mam taki kod:
#include <iostream>
#include <new>
void f(){
char buffer[100]; //tablica automatyczna o zasięgu wewnętrznym
int *pt = new(buffer) int{10}; //utworzenie
std::cout<<(void*)buffer<<std::endl; //adres (jedna z metod dostepu)
std::cout<<*pt<<std::endl; //wartosc (jedna z metod dostepu)
}
int main(){
f();
int* s = (int*)0x6dfe68; //&buffer[0] (popatrzcie na to z przymrużeniem oka)
std::cout<< *s <<std::endl;
*s = 45; //normalna praca ma wskazniku
std::cout<< *s <<std::endl;
}
W funkcji f() dynamicznie tworzymy obiekt danych typu int pod adresem pierwszego elementu tablicy buffer (ona jest lokalna i podlega przydziałowi dynamicznemu więc ginie po zakończeniu działania bloku kodu w którym się znajduje). Do zapisania int'a potrzebujemy wykorzystać cztery pierwsze elementy tablicy buffer ( bo każdy element ma 1B a int u mnie zajmuje 4B).
Po zakończeniu działania funkcji odwołujemy się do adresu tablicy (dokładniej jej zerowego indeksu) gdzie został przydzielony dynamicznie obiekt danych. 0x6dfe68 to odpowiedni adres, wiem... funkcja f() mogła by go zwrócić ;)
Samo to że wartość zapisaną pod tym adresem można odczytać mnie nie dziwi ( bo wartości pozostają w ram'ie) . Jednak można na niej pracować:
*s = 45;
Kiedy mamy zwykłą funkcje zwracającą adres zmiennej lokalnej to nie możemy nic pod nim grzebać bo program się wysypie ( albo kompilator nie dopuści do kompilacji czegoś takiego ). Tu na natomiast można traktować ten adres jak by był przez coś zarezerwowany. Czy wynika to z zasady działania operatora new? Czy może program działa poprawnie przypadkiem? Czy taka sytuacja jest poprawna?
A takie coś:
int* s = new((int*)0x6dfe56) int[3]{12,3,5};
std::cout<<s[0]<<std::endl;
std::cout<<s[1]<<std::endl;
std::cout<<s[2]<<std::endl;
Pod s[0] jest poprawna wartość a pod resztą głupoty... Jaki typ domyślnie jest pod tym (ogólnie przykładowym) niezarezerwowanym adresem?
Dziękuje wam bardzo za informacje i serdecznie pozdrawiam ;)