Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.02.2012, 00:57   #1
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию Переполнение стека

В процессе разработки одной программы появилась ошибка :

В конечном итоге оказалось , что код
Код:
var
  Form1: TForm1;
   FName: string;
   f: TStringList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  f:= TStringList.Create;
end;

procedure TForm1.Button1Click(Sender: TObject); // загрузить файл
begin
  if OpenDialog1.Execute then
  begin
     FName:= OpenDialog1.FileName;
     f.LoadFromFile(FName);
     Memo1.Lines:= f;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); // закрытие программы
begin
  Close;
end;

end.
вызывает эту ошибку, а именно процедура TForm1.FormClose - закрытие программы любым "виндоусовским" способом.
Но если я на форму добавлю кнопку "Закрыть программу" (Button2), то в почти аналогичном коде переполнения стека нет, ошибки нет:
Код:
var
  Form1: TForm1;
   FName: string;
   f: TStringList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  f:= TStringList.Create;
end;

procedure TForm1.Button1Click(Sender: TObject); // загрузить файл
begin
  if OpenDialog1.Execute then
  begin
     FName:= OpenDialog1.FileName;
     f.LoadFromFile(FName);
     Memo1.Lines:= f;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject); // закрыть программу
begin
  Close;
end;

end.
Так все таки, почему переполнение стека?
И не сомневайся даже ... отдых - кайф, работа - лажа!
DeKot вне форума Ответить с цитированием
Старый 02.02.2012, 01:06   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Код:
var
  Form1: TForm1;
   FName: string;
   f: TStringList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  f:= TStringList.Create;
end;

procedure TForm1.Button1Click(Sender: TObject); // загрузить файл
begin
  if OpenDialog1.Execute then
  begin
     FName:= OpenDialog1.FileName;
     f.LoadFromFile(FName);
     Memo1.Lines:= f;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject); // закрыть программу
begin
  {
   А освобождать f кто будет? 
  }  
Close;
end;
Вы создаёте список строк(глобальная переменная у вас оно), создаёте его в FormCreate и там же забиваете строками.
Но кто его освободит? Сам о себе он не позаботится.

В OnDestroy
Код:
FreeAndNil(f);
Человек_Борща вне форума Ответить с цитированием
Старый 02.02.2012, 01:06   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в первом случае рекурсия, так как вы из события OnClose вызываете Close, который вызывает OnClose, и тд.

Человек_Борща, поправка верна, но в данном случае она все равно помрет.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 02.02.2012, 01:23   #4
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

Человек_Борща - первое, что пробовал - это, конечно < f. Free>, эффект тот же.
Цитата:
Но кто его освободит?
Насколько я знаю (может и ошибаюсь) Delphi при корректном закрытии приложения сама (Дельфа - она) очищает память, стеки и т. п. Здесь другой случай.
Пепел Феникса - т.е. я так понимаю, что если применять метод TForm1.FormClose ( для формы, а значит и для всей проги, если она однооконная), то в процедуре надо выполнять какие то действия, связанные с програмными параметрами (например - сохранить значения в файл, или отключить устройство перед закрытием).
В принципе, ответ на свой вопрос я получил - ключевое слово "рекурсия".
Не думал (не знал), что метод OnClose - Close вызывает бесконечную рекурсию.
Всем СПАСИБО!
И не сомневайся даже ... отдых - кайф, работа - лажа!

Последний раз редактировалось DeKot; 02.02.2012 в 01:34.
DeKot вне форума Ответить с цитированием
Старый 02.02.2012, 01:28   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Пепел Феникса - т.е. я так понимаю, что если применять метод TForm1.FormClose ( для формы, а значит и для всей проги, если она однооконная), то в процедуре выполнять какие то действия, связанные с програмными параметрами (например - сохранить значения в файл, или отключить устройство перед закрытием).
ну обычно это делают в OnDestroy, но тут нет разницы для главной формы.
я вообще люблю делать модули независимыми(нет глоб переменных, только поля, все что надо создается/грузиться в OnCreate или по ходу работы с формой этой, а в OnDestroy уничтожаеться/сохраняеться)
Цитата:
Не думал (не знал), что метод OnClose - Close вызывает бесконечную рекурсию.
бывает)
OnClose возникает именно после Close(ну не только поидее), потому у вас непрямая рекурсия.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SendMessage переполнение стека LesnikFFF Общие вопросы Delphi 5 01.07.2011 15:02
Переполнение аппаратного стека Levsha100 Свободное общение 6 13.07.2010 01:59
Переполнение стека NoHeart Общие вопросы Delphi 8 08.11.2009 16:03
Переполнение стека Ake Паскаль, Turbo Pascal, PascalABC.NET 3 30.05.2009 22:39
Переполнение Стека Викдон Паскаль, Turbo Pascal, PascalABC.NET 0 19.12.2008 19:16