New() Assigned() FreeAndNil()

0

Witam wszystkich. Mam mały kłopot ze zwalnianiem pamięci, a mianowicie:

Tworze sobie wskaźnik do rekordu:
PDokument = ^TDokument;

Potem przy tworzeniu formy mam:
pDok : pDokument;
New(pDok);
// jakiś tam kod

W trakcie działania programu, po zatwierdzeniu zmian mam:
// cos tam - jakiś kod
Dispose(pDok);

Przy zamykaniu formy sprawdzam czy dokument został zakończony:

  if Assigned(pDok) then 
    begin
      ....... // tu komunikat aby wcześniej zatwierdzić dokument itd.
      CanClose := False;
    end;

I teraz już, zbaraniałem. Bo przy czymś takim zawsze wykonuje to co w IF-ie jest

  New(pDok);
  Dispose(pDok);

  if Assigned(pDok) then
    begin
      // ta część się wykonuje, a nie powinna
    end;

Czytałem że zamiast Free; lepiej użyć Dispose();
Czy w takim razie mam po każdym Dispose() dodawać jeszcze pDok := NIL ?

Mogę użyć FreeAndNil() zamiast Dispose(), ale w czasie działania programu w kilku miejscach sprawdzam, lub zwalniam pamięć i wtedy mi się wykrzacza AccessVolation.

Jak najlepiej (najbezpieczniej) allokować, zwalniać i sprawdzać w takim razie wskaźniki na rekordy ?

0

Czesc.

_Decho napisał(a)

I teraz już, zbaraniałem. Bo przy czymś takim zawsze wykonuje to co w IF-ie jest

  New(pDok);
  Dispose(pDok);

  if Assigned(pDok) then
    begin
      // ta część się wykonuje, a nie powinna
    end;

Wykonuje sie poniewaz, cytat z helpa:

After a call to Dispose, the value of P is undefined and it is an error to reference P

Czyli Dispose zwalnia pamiec jednak nie ustawia wskaznika na nil, nie mozesz wiec uzywac Assigned();

_Decho napisał(a)

Czy w takim razie mam po każdym Dispose() dodawać jeszcze pDok := NIL ?

Tak albo napisz sobie wrapper na Dispose i w nim zawrzyj po Dispose "nillowanie" wskaznika.

_Decho napisał(a)

Mogę użyć FreeAndNil() zamiast Dispose(), ale w czasie działania programu w kilku miejscach sprawdzam, lub zwalniam pamięć i wtedy mi się wykrzacza AccessVolation.

Otoz nie mozesz, gdyz wczesniej pisales ze tworzysz rekord natomiast help Delphi mowi:

Warning: Obj must be an instance of a TObject descendant.

_Decho napisał(a)

Jak najlepiej (najbezpieczniej) allokować, zwalniać i sprawdzać w takim razie wskaźniki na rekordy ?

Moze byc tak jak to robisz, tylko ustawiaj zwolniony wskaznik na nil ;)</quote>

0

Dzięki za pomoc.
Do każdego Dispose() dodałem pdok := NIL; i wszystko jest OK.
Zastanawiałem się tylko czy jest może jakiś inny lepszy sposób albo zamiast Dispose() albo zamiast Assigned() ?

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