SIGSEGV na close modal formy

0

Siema.

Otwieram formularz przez ShowModal. Formularz ma grida i zapisuje/odczytuje coś z bazy danych. Po odczycie robię self.Close; i wywala mi SIGSEGV w TCustomForm.CloseModal a konkretnie na instrukcji if CloseQuery then . Przypuszczam, że coś jest nie tak z zamykaniem tej formy - czy należy wykonać cokolwiek jeszcze przed self.Close ??

0
  1. zamiast Close użyj ModalResult := mrCancel
  2. nie masz przypadkiem czegoś w OnCloseQuery formy?
0

@serge - którą masz wersję Lazarusa?

Sprawdziłem z niedowierzenia i muszę stwierdzić, że nie ma żadnego problemu z zamykaniem przez Close formularza wywołanego modalnie; Ani formularza tworzonego automatycznie, ani dynamicznie, więc problem musi leżeć gdzie indziej;

Jeśli masz jakikolwiek problem z kodem to go przedstaw, bo nikomu raczej nie będzie się chciało zgadywać.

0

Podany sposób też nie działa.

Kod tworzący forme

begin
  zapisf := TFormaZapisu.Create(nil);
  zapisf.SetList(Lista);
  zapisf.ShowModal;
  ParseDelimited(ToDoMemo.Lines,Lista,'\n');
end;

kod zamykające forme, już na formie :

procedure TFormaZapisu.Button1Click(Sender: TObject);
begin
  SaveList;
  ModalResult := mrCancel;
end;    

Może zalinkujcie jakimś docsem nt. zamykania modali - nie mogę nic znaleźć...

0
zapisf.SetList(Lista);

To mi nie wygląda na standardową metodę TForm. A przy okazji to SaveList bym wywołał w OnClose formy.

1
zapisf := TFormaZapisu.Create(nil);

Jeśli tworzysz formularz dynamicznie, to do konstruktora w parametrze AOwner (lub TheOwner - są dwa konstruktory, ale argumenty tego samego typu - TComponent) przekazuj formularz-rodzic, najbezpieczniej wykorzystać do tego celu Self, czyli:

zapisf := TFormaZapisu.Create(Self);   { słabe nazewnictwo }

Poza tym w kodzie tworzącym formularz brakuje zwolnienia z pamięci obiektu zapisf, więc po ShowModal wywołaj metodę Free; No chyba, że ten formularz zwalniasz gdzie indziej niż w podanym bloku i zmienna zapisf jest np. polem klasy głównego formularza lub globalną zmienną (argh!);

babubabu napisał(a)

A przy okazji to SaveList bym wywołał w OnClose formy.

A ja bym polecał nie OnClose, tylko OnDestroy, bo jeśli ten dynamicznie tworzony formularz ma jakąś implementację zdarzenia OnCloseQuery, to trzeba by upewnić się, że po anulowaniu zamknięcia formularza metoda SaveList nie zostanie wywołana; Jeśli zapis ma się odbyć tylko raz (przy zwalnianiu formularza z pamięci), to najodpowiedniejsze do tego celu jest zdarzenie OnDestroy;

@serge - to nie implementacja klasy TForm jest wadliwa, tylko Twój kod; Sam formularz zwolni się z pamieci poprawnie, o ile prawidłowo go utworzysz i prawidłowo zwolnisz; Ty go nie zwalniasz z pamięci, więc dodaj wywołanie metody Free lub skorzystaj z FreeAndNil (jeśli to konieczne) na zmiennej zapisf i wtedy sprawdź;

Nie znamy także metod SetList oraz SaveList, a w nich może czaić się zło.

0

Siema. Problemem było SetList; Nie potrafię jednak naprawić problemu. Kodu pokazać teraz nie mogę - zrobię to wieczorem. Generalnie, mam wskaźnik w formie zapisu, któy w SetList ustawiam jakimś adresem, potem piszę do zmiennej z pod wskaźnika a na koniec ustawiam wskaźnik na nil i zamykam forme i się sypie. Jak nie ustawie tego wskaźnika na zmienną z formy rodzica to jest spoko ... Dlaczego tak się dzieje ?

0

Generalnie, mam wskaźnik w formie zapisu, któy w SetList ustawiam jakimś adresem, potem piszę do zmiennej z pod wskaźnika a na koniec ustawiam wskaźnik na nil i zamykam forme i się sypie.

Jeżeli na formularzu modalnym masz jakiś wskaźnik (ale jaki i po co to musisz napisać), do którego wpisujesz adres np. dynamicznie zaalokowanej przestrzeni, to w destruktorze formularza (lub wcześniej, jeśli to konieczne) zarezerwowaną pamięć musisz zwolnić - **Nil**owanie zmiennej nie dealokuje pamięci automatycznie;

Jeśli chodzi o samo "sypanie się", to musisz napisać coś więcej (dużo więcej), bo my tutaj raczej wróżyć nie umiemy; Być może wskaźnik **Nil**ujesz, a w późniejszej części kodu próbujesz z niego skorzystać i SIGSEGV gotowy; Dlatego ważne jest, abyś podał ten kod - wtedy będzie można coś doradzić.

0

Na formie rodzicu mam stringa, do formy zapisu przekazuje wskaźnik, bo chcę zapisać to co jest w tej zmiennej i odczytac coś nowego i zapisać do tej samej zmiennej, tak, że jak wyjdę z formyzapisu to wartość na formie rodzicu zostanie zmodyfikowana. Niluje wskaźnik bo ta zmienna nadal żyje - w formie rodzicu.Mam nadzieję, że rozumiesz o co mi chodzi. W jaki inny sposób można by taką funkcjonalność zorganizować??

0

słyszałeś oczywiście o czymś takim jak przekazywanie zmiennej przez var i pokaż wreszcie kod

0
serge napisał(a)

Niluje wskaźnik bo ta zmienna nadal żyje - w formie rodzicu.

Rozumiem teraz do czego jest ten wskaźnik i po co go przekazujesz; Teraz zastanów się, jak z**Nil**owanie wskaźnika może wpłynąć na zwalnianie klasy formularza z pamięci; Według mnie nijak, pod warunkiem, że dalszy kod formularza modalnego już nie korzysta z tego wskaźnika; Jeżeli natomiast korzysta, to spowoduje wyjątek naruszenia pamięci;

No i tak jak wspomniał poprzednik - możesz też skorzystać z przekazania łańcucha przez referencję, więc zmiany zostaną wprowadzone także w łańcuchu w głównym formularzu.

0

Koledzy. Nie używam później tej zmiennej, tylko niluje. Wszystko jest ok, ale kwestia tego typu, że ja przekazywałem przez wartość zmienną, co znaczyło, że tworzona była zmienna lokalna i potem ustawiałem wskaźnik na jej adres, co po wyjściu z funkcji ustawiającej było nonsensem. Innymi słowy wpisywałem coś w obszar pamięci i później chyba przy niszczeniu formy się złego z pamięcią działo. Wybaczcie zamieszanie, ale to był idiotyczny błąd. Jak @abrakadaber napisał VAR to już wiedziałem w czym problem, ale chciałem sprawdzić. Niemniej dziękuję wam, bo jak zawsze wykazaliście się chęcią pomocy i intuicją ;)

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