trzeci
#programowanie #cpp
Skąd operator delete wie ile ma uwolnić pamięci?

class A {
public:
virtual ~A();
int a;
}
class B: public A {
public:
int b;
}

-----

A* aPtr = new B;
delete aPtr;

wirtualne konstruktory działają fajnie. Na początku zakładałem, ze delete rozmiar czerpie z przekazanego pointera. Ale powyższy przykład burzy tę teorię. Gdzieś musi być trzymany rozmiar, aby poprawnie kod zadziałał. Gdzie? vtables, czy może gdzieś przy kodzie destruktora?
  • Najlepsze
  • Wszystkie komentarze
M4ks
M4ks
M4ks
3
heapie jak alokuja blok pamieci to w nim tez zapisuja rozmiar i inne rzeczy. Podejrzewam ze moze byc podobnie.


@msgreen: dokladnie tak jest, glowy nie dam, ale pierwsze 4 bajty to zdaje sie rozmiar obiektu
mikkeboss
@Daredzik: ale p--------z..
m.....n
m.....n
@trzeci: nie jestem pewny co do delete ale malloc/free w C dzialaja tak ze na heapie jak alokuja blok pamieci to w nim tez zapisuja rozmiar i inne rzeczy. Podejrzewam ze moze byc podobnie.
mikkeboss
@Daredzik: nie, raczej "nie znam się, ale się wypowiem" najgorszy rak internetu.
vipe
vipe
2
@trzeci: http://stackoverflow.com/questions/7514365/does-the-delete-operator-work-with-dynamically-allocated-memory-returned-throu
oraz dla tablic:
http://stackoverflow.com/questions/2327848/how-does-the-delete-in-c-know-how-many-memory-locations-to-delete

Wygląda na to, że każdy kompilator robi to po swojemu, że jest to kwestia implementacji kompilatora. Zwykle rozmiar zaalokowanej pamięci jest gdzieś zapisywany, a w pierwszym linku są dwa tego przykłady.
m.....n
m.....n
@M4ks: tak, zaleznie od implementacji 4 lub 8 bajtow,poza rozmiarem zapisywany tam jest tez np. adres kolejnego wolnego obszaru heapa.
CHI77OUT
@mikkeboss: takich pajacykōw tu nie brak..
KrzaQ2
@trzeci: Spoko, odpowiedź na pytanie które chciałeś zadać teƶ udzieliłem.
mikkeboss
@Daredzik: raczej ty sobie zastosuj maść na głupotę
KrzaQ2
@trzeci: Nie ma czegoś takiego jak wirtualny konstruktor.

Za to destruktor to zwyczajna funkcja, jeśli jest wirtualny to po prostu (to juƶ kwestia implementacji, standard nie nakazuje takiej) jego adres jest jednym z adresów w vtable, więc nie ma problemów z wywołaniem destruktora dla dynamicznego typu pod wskaźnikiem.
mikkeboss
@CHI77OUT: no niestety. Poza tym zwalnianie bajt po bajcie trwało by cala wieczność. Dla stosu zwolnienie pamięci to zwykle przesuniecie wskaźnika wierzchołka stosu. Najlepiej zobaczyć w trybie debug. Kliknac w VS disassembly i popatrzeć co się tam dzieje.
@trzeci:
trzeci
trzeci Autor
0
@KrzaQ2: pomyliłem sie, z kodu jsno wynika ze o destruktor mi chodzi
trzeci
trzeci Autor
0
@KrzaQ2: dziękuje
@vipe: dobry materiał, dzięki za najdokładniejsza odpowiedź
p__b
p__b
0
@trzeci: dodaj sobie wypisywanie PRETTYFUCTION_ (czy jakos tak) w dekonstruktorze to zobaczysz co sie dzieje.