AV podczas create i/lub wywołania metody

0

Cześć, mam dość dziwny problem związany z kodowym tworzeniem raportów(aktualnie w fastReports, a w cześniej w ravie był bardzo podobny).

W związku z tym moje pytanie, kiedy podczas tworzenia komponentu lub odwołania do metody utworzonego komponentu może pojawić się Access Violation?

Sytuacja jest o tyle dziwna, że tworzę sobie pewien komponent powiedzmy 4 razy. Za 3 wywala się AV. Jak utworzę go 2 razy, to jest ok, ale następne tworzenie innego komponentu powoduje AV.

Czy może to być związane w jakiś sposób z komponentem TCheckListBox?

0
Juhas napisał(a)

Cześć, mam dość dziwny problem związany z kodowym tworzeniem raportów(aktualnie w fastReports, a w cześniej w ravie był bardzo podobny).

W związku z tym moje pytanie, kiedy podczas tworzenia komponentu lub odwołania do metody utworzonego komponentu może pojawić się Access Violation?

Sytuacja jest o tyle dziwna, że tworzę sobie pewien komponent powiedzmy 4 razy. Za 3 wywala się AV. Jak utworzę go 2 razy, to jest ok, ale następne tworzenie innego komponentu powoduje AV.

Czy może to być związane w jakiś sposób z komponentem TCheckListBox?

Za mało informacji. Pokaż jakiś kod. AV najczęściej wylatuje, jak odwołujesz się do nieistniejącej instancji obiektu (może gdzieś wcześniej jest zwalniana). Można się tego ustrzec sprawdzacjąc:
If Assigned(obiekt) then
Pytanie też co to za komponent, może jest popieprzeone coś w tym komponencie. A może jak go tworzysz to podajesz Owner'a który jest nil'em ?

0

może byś jakiś kod podał

If Assigned(obiekt) then

niczego nie gwarantuje bo jeśli zrobiłeś wcześniej obiekt.free ale nie dałeś obiekt := nill to Assigned zwróci Ci true

0

Chodzi o to, że w kodzie jest wszystko wporządku.
Doszedłem do tego, że może to być kwestia tablic dynamicznych.
Więc zrobiłem taki manewr, że zwiększyłem tablicę dynamiczną od razu do pożądanej wartości(dla testów) i jest lepiej

Czyli dałem raz

setLength(tablica, 3)

zamiast w funkcji wywoływanej 3 razy:

setLength(tablica, length(tablica)+1);

Natomiast teraz błąd pojawia się przy frxReport.ShowReport;

Teraz czasami AV się pojawia, a czasami nie(nigdy nie pojawia się za pierwszym razem).
Raport tworzę analogicznie, jak w ich pomocy.

Wyczytałem, że TCheckListBox powoduje memory leaki(12 bajtów na każdy zaznaczony rekord) i co zmienić, żeby było dobrze. Ale dobrze nie jest. Więc zrezygnowałem z TCheckListBox na rzecz dwóch listBoxów(kolumny dostępne i kolumny widoczne na raporcie), ale jest tak, jak napisałem.

Czy wiadomo Wam o jakiś okolicznościach, w których poprawnie obsługiwane tablice dynamiczne mogą powodować błędy?

PS. Z tego, co wiem to jeśli chodzi o zmienne lokalne, to Delphi sam zwalnia przydzielone im zasoby w odpowiednim momencie, tak?

0
Juhas napisał(a)

Czy wiadomo Wam o jakiś okolicznościach, w których poprawnie obsługiwane tablice dynamiczne mogą powodować błędy?
jak kod jest źle napisany

PS. Z tego, co wiem to jeśli chodzi o zmienne lokalne, to Delphi sam zwalnia przydzielone im zasoby w odpowiednim momencie, tak?
nie

0

Czyli jeśli chcę zwolnić obiekty lokalne w innym miejscu, niz zostały utworzone, to się nie da? W grę wchodzą tylko obiekty globalne?

0

da się tylko trzeba temu innemu miejscu dać odpowiedni wskaźnik na ten obiekt. Po wyjściu z procedury/funkcji/metody/czegokolwiek WSZYSTKIE zmienne lokalne są czyszczone, tylko że nie oznacza to usuwania obiektów a jedynie usunięcie wartości dla zmiennych prostych i łańcuchów (integer, double, record, itp) oraz utratę adresu obiektów (np. forma: TForm to tak naprawdę forma to zwykły int wskazujący adres w pamięci), czyli pamięć pozostaje zajęta ale traci się do niej wskaźnik i jedyna metoda na zwolnienie tej pamięci to zamknięcie aplikacji.

0
Misiekd napisał(a)

może byś jakiś kod podał

If Assigned(obiekt) then

niczego nie gwarantuje bo jeśli zrobiłeś wcześniej obiekt.free ale nie dałeś obiekt := nill to Assigned zwróci Ci true

Znowu tak bym tego nie nazwał że nic nie gwarantuje. Assigned stosowane rozważnie jest IMHO bardzo pomocne.

Misiekd napisał(a)

bo jeśli zrobiłeś wcześniej obiekt.free ale nie dałeś obiekt := nill to Assigned zwróci Ci true

To się oczywiście zgadza, ale wystarczy przywyknąć do robienia FreeAndNil(obiekt). A tak poza tym ja osobiście częściej wykorzystuje Assigned do testów czy jakiś obiekt został już utworzony, a nie czy jeszcze jest. Przy czym staram się zawsze inicjować wstępnie obiekt na nil żeby uniknąć niespodzianek (poza polami klas, gdzie jest to robione automatycznie).

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