wyjątki i przydział pamięci

0

raise Exception.create('tresc');

powyzszy zapis wyrzuca wyjatek. exception jest klasa wiec pamiec jest przydzielana dynamicznei na stercie. czy ten obiekt ma byc gdzies zwolniony czy tym zajmuje sie juz kompialtor?

kozystajac z okazji jeszce jedno pytanie:

tab: array of integer;

SetLenght(tab,20);

dynamiczna tablica. tej pamieci nie mozna zwolnic poprzez dispose(). czy ta pamiec jest zawalniana automatycznie gdy tab traci zakres waznosci?
w kompedium jest przyklad gdzie ort!:
tab := nil;
i to ma zwalniac pamiec?

0
banita21 napisał(a)

raise Exception.create('tresc');

powyzszy zapis wyrzuca wyjatek. exception jest klasa wiec pamiec jest przydzielana dynamicznei na stercie. czy ten obiekt ma byc gdzies zwolniony czy tym zajmuje sie juz kompialtor?

kompilator

tab: array of integer;

SetLenght(tab,20);

dynamiczna tablica. tej pamieci nie mozna zwolnic poprzez dispose(). czy ta pamiec jest zawalniana automatycznie gdy tab traci zakres waznosci?
w kompedium jest przyklad gdzie pisze:
tab := nil;
i to ma zwalniac pamiec?
tak

0

co to drugiego pytania to odpowiedz dotyczy tego ze tablica po wyjscu poza zakres jest zwalniana czy to ze tab := nil zwalnia pamiec? czy jedno i drugie jest poprawne.

0

W momencie deklarowania tablicy na np 20 elementów rezerwowana jest pamięć na 20 elementów, deklarujesz tablice na 3 elementy pamiec rezerwowana na 3 elementy reszta zwalniana, dajesz nil kasujesz cały przydział pamięci.

0

Ale niektórzy gadają, że tablic dynamicznych nie trzeba zwalniać. Jeśli są lokalne.
Cóż, ja zwalniam zawsze.

0
banita21 napisał(a)

co to drugiego pytania to odpowiedz dotyczy tego ze tablica po wyjscu poza zakres jest zwalniana czy to ze tab := nil zwalnia pamiec? czy jedno i drugie jest poprawne.

ale tam niegdzie nie było o wyjściu poza zakres - było tylko 'zakres ważności' czego niestety nie byłem w stanie wpasować w nic konkretnego

  1. jak wyjdziesz poza zakres to
    a) jak masz szczęście to dostaniesz w odpowiedzi śmieci
    b) jak masz pecha to AV
  2. tablic dynamicznych nie trzeba zwalniać (działają prawie jak typ string), ale tak samo jak masz stringa lokalnie w procedurze, który ma 1G danych w sobie, a jest już niepotrzebny ale procedura jeszcze trwa to wypadało by przypisać mu '' tak samo jest z tablicami - jak zajmują dużo a są niepotrzebne to albo := nil albo SetLength( , 0) - oba zwalniają pamięć.
    Jak nie zwolnisz ręcznie tablicy dynamicznej to zwalnia się ona przy wyjściu z procedury (przy lokalnych tablicach), przy zniszczeniu obiekty (przy tablicach jako zmienne klasy) i po zakończeniu programu (przy zmiennych globalnych).

Inna sprawa, że jak masz tablicę tablic to trzeba każdą 'podtablicę' zwalniać osobno.
A jeszcze inna sprawa, że jak masz tablicę obiektów to obiekty się nie zwalniają automagicznie.

0

w przypadku tablicy obiektow:
tab: array of TKlasa;

skoro kazda instancja klasy jest tak naprawde wskaznikiem wiec zakladam ze nie dziala tu zaden konstruktor domyslny(o ile takowe wystepuja?).
czy po nadaniu tablicy wymiaru musimy w petli przeleciec calosc i wywolac konstruktor dla kazdego elementu?

SetLength(tab,12);

for ...
tab[x] = TKlasa.Create(...); ?

i pozniej analogicznie wywolac Free?


mam jeszcze takie pytanie odnosnie zwalniania zasobow.
w c++builder (help) jest napisane ze nie nalzey wywolywac Free() tylko uzywac delete czy innych ktore samodzielnie opracujemy. w kompedium wyczytalem ze zwolnienie zasobu odbywa sie poprzez jawne wywolanie destruktora Destroy() badz za pomoca metody Free(), z tym ze autor pisze iz lepiej stosowac Free bo ta przypisuje nil i ponowne zwolnienie nie wywoluje bledu. jak to z tym jest?
Free musi byc metoda TObject. czy ta metoda <ort>po prostu </ort>wywoluje destruktor? tylko skad wie ktory(ktorej klasy) destruktor ma wywolac? pytam poniewaz w builderze ten mechanizm nie funkcjonuje.

0
banita21 napisał(a)

w przypadku tablicy obiektow:
tab: array of TKlasa;

skoro kazda instancja klasy jest tak naprawde wskaznikiem wiec zakladam ze nie dziala tu zaden konstruktor domyslny(o ile takowe wystepuja?).
czy po nadaniu tablicy wymiaru musimy w petli przeleciec calosc i wywolac konstruktor dla kazdego elementu?

SetLength(tab,12);

for ...
tab[x] = TKlasa.Create(...); ?

i pozniej analogicznie wywolac Free?

Tak.
Po pierwsze - wskaźnik też zajmuje jakieś miejsce w pamięci.
Po drugie - wskaźnik wskazuje na pewne miejsce w pamięci. A dokładniej rzecz biorąc na pewien obszar, który zajmuje dany obiekt.

Jeśli nie zwolnisz tego obiektu, wskaźnik dalej będzie na tamten obszar wskazywał i będzie on uważany za używany. Dopiero po wywołaniu free* wskaźnik zostaje zdjęty ze stosu, a obszar, na który wskazywał jest uważany za nieużywany i kompilator będzie w tamtym miejscu zapisywał inne rzeczy.

free nie musisz wywoływać jeśli obiekt jest tworzony lokalnie w następujący sposób:

procedure Procedura;
var
  myObj: TMyObject;
begin
  myObj:=TMyObject.Create;
end;

w tym wypadku obiekt zostanie zwolniony po wyjściu z procedury. Jednak ja dla świętego spokoju zawsze zwalniam ręcznie.

0
Juhas napisał(a)

free nie musisz wywoływać jeśli obiekt jest tworzony lokalnie w następujący sposób:

procedure Procedura;
var
  myObj: TMyObject;
begin
  myObj:=TMyObject.Create;
end;

w tym wypadku obiekt zostanie zwolniony po wyjściu z procedury. Jednak ja dla świętego spokoju zawsze zwalniam ręcznie.

a kto cię tak okrutnie okłamał??? NIGDY obiekt nie jest zwalniany sam z siebie (poza wątkami z FreeOnTerminated ustawionym na True i VCLem, który ma przypisanego Owner'a)
Tutaj po wyjściu z procedury tracisz wskaźnik do obiektu a pamięć przez niego zajęta jest niedostępna aż do końca działania aplikacji!

0
Misiekd napisał(a)

Tutaj po wyjściu z procedury tracisz wskaźnik do obiektu a pamięć przez niego zajęta jest niedostępna aż do końca działania aplikacji!

A to nie jest tak, że wskaźnik jest zdejmowany i skoro już nic nie wskazuje na dany obszar, to jest on wolny do użycia?

0

delphi nie ma GC, a tak jak piszesz działają jedynie interfejsy

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