Страница 1 из 2

TStringList

Добавлено: 30 авг 2018, 10:26
jurist23rus
Я вроде не первый день пишу скрипты и меня уже трудно удивить каким-нибудь кривыми кодом :) Но сегодня тот случай когда я удивлён. У меня не уничтожается TStringList, через несколько секунд после вызова деструктора (неважно как FreeObj () или просто Free) просто тихий вылет из программы. Проверьте кто-нибудь у себя. Может у меня что-то с компом, ибо ошибка в таком классе уже бы давно нашлась сама, очень уж он популярный, а я столкнулся с этим впервые.

Кстати, вылеты происходят чаще, если открыто окно отладчика. Попытка посмотреть в отладчике содержимое переменной SL после её уничтожения у меня гарантировано приводит к зависанию или вылету.
TSTRINGLIST.ZIP
(44.14 КБ) 64 скачивания

Re: TStringList

Добавлено: 30 авг 2018, 10:44
Гocть
jurist23rus писал(а):через несколько секунд после вызова деструктора (неважно как FreeObj () или просто Free) просто тихий вылет из программы. Проверьте кто-нибудь у себя.
Нет такого.

Re: TStringList

Добавлено: 30 авг 2018, 10:51
admin
FreeObj не обнуляет указатель. Pascal Script не позволяет передавать в var-параметр объект-потомок.

Re: TStringList

Добавлено: 30 авг 2018, 11:01
jurist23rus
Ещё потестил. Думаю подавляющее большинство вылетов связано с отладчиком - попытка посмотреть переменную уничтоженного объекта убивает приложение.

Вылеты приложения, в случаях когда отладчик не запущен, скорее всего возникают при попытке уничтожить уже уничтоженный объект, так как FreeObj, как выяснилось, не освобождает переменную.

Re: TStringList

Добавлено: 30 авг 2018, 11:06
jurist23rus
admin писал(а):FreeObj не обнуляет указатель. Pascal Script не позволяет передавать в var-параметр объект-потомок.


Объясните пожалуйста, в каких случаях FreeObj () обнуляет переменную, а в каких нет? А то нет понимания его правильного использования, что приводит к ошибкам.

Re: TStringList

Добавлено: 30 авг 2018, 11:26
admin
FreeObj никогда не обнуляет указатель.

Re: TStringList

Добавлено: 30 авг 2018, 11:32
jurist23rus
Для меня это открытие. Я думал FreeObj выступает аналогом FreeAndNil из Lazarus. А зачем тогда нужен FreeObj и чем он отличается от стандартного Free?

Нашёл старую тему об этом. Но мой вопрос всё равно в силе.

Re: TStringList

Добавлено: 30 авг 2018, 11:42
Гocть
jurist23rus писал(а):А зачем тогда нужен FreeObj и чем он отличается от стандартного Free?

Для определения: существует ли объект и уничтожения его без ошибки, возникающей при вызове Free для уже уничтоженного объекта.
Пример:

Код: Выделить всё

procedure FreeObj2(Sender: TObject);
begin
if Sender<>nil
then
Sender.Free;
end;

///////////////////////////////////

var T:TTimer;

procedure Test(Sender: TObject);
begin
debug(time)
end;

procedure CreateTimer(Sender: TObject);

begin
 T:=TTimer.Create(nil);
 T.Interval:=1000;
 T.Enabled:=true;
 T.OnTimer:=@test;
end;

procedure FreeTimer(Sender: TObject);
begin
FreeObj2(T);
end;


procedure Form_Create;
begin
dxButton1.OnClick:=@CreateTimer;
dxButton2.OnClick:=@FreeTimer;
end;

Re: TStringList

Добавлено: 30 авг 2018, 12:01
jurist23rus
По-моему неудачный пример.

FreeObj2 сработает корректно только в случае если T=nil. Она не позволит унчтожить T, ибо не будет пройдена проверка Sender<>nil.

В остальных же случаях очень легко схлопотать ошибку, достаточно просто лишний раз нажать на dxButton2. В первое нажатие T будет уничтожено, но так как переменная T не обнулена, то есть ещё содержит ссылку на несуществующий объект, то при повторном нажатии вы будете уничтожать, то чего нет и конечно это будет фиаско ;) .

Re: TStringList

Добавлено: 30 авг 2018, 12:12
Гocть
Ну или так:

Код: Выделить всё

procedure FreeObj2(Sender: TObject);
begin
  try
     Sender.Free;
  except
  end;
end;