Ile będzie zmiennych w pamięci po wykonaniu programu?

0
void main() {
  int x=3, *y=new int, *z=new int;
  y= &x;
  *z = x;
  y= new int;
  delete y; 
}

Na początku jest deklaracja zmiennej x. Później przydzielanie pamięci dla zmiennych dynamicznych y i z. Dalej zmienna y wskazuje na x, ale w pamięci zostaje śmieć. później znów dla zmiennej y przydziela się pamięć, więc tworzy się kolejny śmieć. na końcu usuwa się zmienną y.

Czyli w pamieci zostaną 4 zmienne?

1

Podstawowa zasada to każdemu new musi odpowiadać delete.

  1. Przypisujesz *y=new int, a potem y= &x; więc masz jeden wyciek pamięci, bo nie zwolniłeś tego, co przydzieliłeś.
  2. Przydzielasz pamięć *z=new int; a potem ustawiasz *z = x, czyli zmieniasz jedynie wartość.

W tym przypadku przydzielasz pamięć i natychmiastowo ją zwalniasz, więc wycieku nie ma:

y= new int;
delete y; 

Po wyjściu z maina teoretycznie zostaje pamięć potrzebna na 2 inty.

0

IMHO w pamięci zostają 2 zmienne/śmieci.

  1. x zadeklarowane statycznie zostanie sprzątnięte na końcu bloku }.
  2. y wskazuje na wartość x, ale nie przydziela nowej pamięci.
  3. Wskaźnikowi z przypisujemy wartość x. Nie przydziela to nowej pamięci. z ma pamięć przydzieloną na początku.
  4. Potem przydzielamy nową pamięć dla y, nie zwalniając starej (co i tak w tym momencie zwolniło by x).
  5. No i zwalniamy pamięć y, niestety dopiero tą przydzieloną w 4.
0

Polecam: http://www.pythontutor.com/visualize.html -- ułatwi Ci śledzenie, a pokazuje też (eksperymentalnie) C i C++. Co prawda wycieków nie widać, ale można zauważyć, co zniknęło bez delete. (Przy śledzeniu na tej stronie warto dodać return 0; na końcu, żeby się zatrzymało przed wyjściem z main).

No i widać, że wyciekają dwa int-y -- jeden zaalokowany na początku pod *y, ale zgubiony w linii 3, a drugi zaalokowany na początku pod *z, a niezwolniony (choć niezgubiony).

1

To ile pamięci wycieka, można łatwo wywnioskować z prostych obliczeń – new używane jest 3x (dwa na początku i jedno na końcu), a delete tylko raz, więc 3 - 1 = 2. ;)


Nie macie jakiegoś konkretnego narzędzia do śledzenia operacji na pamięci i detekcji wycieków? Na pewno macie, wystarczy użyć i nie zastanawiać się niepotrzebnie. Przeportowałem kod pod FPC:

var
  X: Integer;
  Y, Z: PInteger;
begin
  X := 3; New(Y); New(Z);
  Y := @X;
  Z^ := X;
  New(Y);
  Dispose(Y);
end.

i z modułem HeapTrc wypluwa taki wynik:

Heap dump by heaptrc unit
3 memory blocks allocated : 12/24
1 memory blocks freed     : 4/8
2 unfreed memory blocks : 8
True heap size : 65536 (128 used in System startup)
True free heap : 65248
Should be : 65264
Call trace for block $0005F168 size 4
Call trace for block $0005F118 size 4

Wynik – 2 unfreed memory blocks : 8.

1 użytkowników online, w tym zalogowanych: 0, gości: 1