Wpis z mikrobloga

#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?
  • 18
  • Odpowiedz
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
  • Odpowiedz
@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.
  • Odpowiedz
@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.
  • Odpowiedz
@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:
  • Odpowiedz