Последняя версия DataExpress 3 beta от 7 декабря 2019 года.
Изображение Скачать | Изображение Что нового?
См. также: Энциклопедия DX | Форум на develop-soft | Песочница
ИзображениеИзображениеИзображение

TStringList

Все о том как сделать что-то с помощью скриптов.
jurist23rus
Эксперт
Сообщения: 2657
Зарегистрирован: Пт сен 30, 2016 9:42 am
Откуда: Майкоп
Благодарил (а): 2 раза
Поблагодарили: 13 раз

TStringList

Сообщение jurist23rus » Чт авг 30, 2018 10:26 am

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

Кстати, вылеты происходят чаще, если открыто окно отладчика. Попытка посмотреть в отладчике содержимое переменной SL после её уничтожения у меня гарантировано приводит к зависанию или вылету.
TSTRINGLIST.ZIP
(44.14 КБ) 32 скачивания
Destiny is a very convenient word for those who never take decisions.

Аватара пользователя
Гocть
Эксперт
Сообщения: 1586
Зарегистрирован: Пн ноя 27, 2017 8:02 am
Поблагодарили: 9 раз

Re: TStringList

Сообщение Гocть » Чт авг 30, 2018 10:44 am

jurist23rus писал(а):через несколько секунд после вызова деструктора (неважно как FreeObj () или просто Free) просто тихий вылет из программы. Проверьте кто-нибудь у себя.
Нет такого.
Фрилансер. Разработка на заказ. Консультирование.

Аватара пользователя
admin
Разработчик
Сообщения: 4630
Зарегистрирован: Пн мар 14, 2016 11:32 am
Откуда: Ленинградская
Благодарил (а): 20 раз
Поблагодарили: 95 раз

Re: TStringList

Сообщение admin » Чт авг 30, 2018 10:51 am

FreeObj не обнуляет указатель. Pascal Script не позволяет передавать в var-параметр объект-потомок.

jurist23rus
Эксперт
Сообщения: 2657
Зарегистрирован: Пт сен 30, 2016 9:42 am
Откуда: Майкоп
Благодарил (а): 2 раза
Поблагодарили: 13 раз

Re: TStringList

Сообщение jurist23rus » Чт авг 30, 2018 11:01 am

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

Вылеты приложения, в случаях когда отладчик не запущен, скорее всего возникают при попытке уничтожить уже уничтоженный объект, так как FreeObj, как выяснилось, не освобождает переменную.
Destiny is a very convenient word for those who never take decisions.

jurist23rus
Эксперт
Сообщения: 2657
Зарегистрирован: Пт сен 30, 2016 9:42 am
Откуда: Майкоп
Благодарил (а): 2 раза
Поблагодарили: 13 раз

Re: TStringList

Сообщение jurist23rus » Чт авг 30, 2018 11:06 am

admin писал(а):FreeObj не обнуляет указатель. Pascal Script не позволяет передавать в var-параметр объект-потомок.


Объясните пожалуйста, в каких случаях FreeObj () обнуляет переменную, а в каких нет? А то нет понимания его правильного использования, что приводит к ошибкам.
Destiny is a very convenient word for those who never take decisions.

Аватара пользователя
admin
Разработчик
Сообщения: 4630
Зарегистрирован: Пн мар 14, 2016 11:32 am
Откуда: Ленинградская
Благодарил (а): 20 раз
Поблагодарили: 95 раз

Re: TStringList

Сообщение admin » Чт авг 30, 2018 11:26 am

FreeObj никогда не обнуляет указатель.

jurist23rus
Эксперт
Сообщения: 2657
Зарегистрирован: Пт сен 30, 2016 9:42 am
Откуда: Майкоп
Благодарил (а): 2 раза
Поблагодарили: 13 раз

Re: TStringList

Сообщение jurist23rus » Чт авг 30, 2018 11:32 am

Для меня это открытие. Я думал FreeObj выступает аналогом FreeAndNil из Lazarus. А зачем тогда нужен FreeObj и чем он отличается от стандартного Free?

Нашёл старую тему об этом. Но мой вопрос всё равно в силе.
Destiny is a very convenient word for those who never take decisions.

Аватара пользователя
Гocть
Эксперт
Сообщения: 1586
Зарегистрирован: Пн ноя 27, 2017 8:02 am
Поблагодарили: 9 раз

Re: TStringList

Сообщение Гocть » Чт авг 30, 2018 11:42 am

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;
Фрилансер. Разработка на заказ. Консультирование.

jurist23rus
Эксперт
Сообщения: 2657
Зарегистрирован: Пт сен 30, 2016 9:42 am
Откуда: Майкоп
Благодарил (а): 2 раза
Поблагодарили: 13 раз

Re: TStringList

Сообщение jurist23rus » Чт авг 30, 2018 12:01 pm

По-моему неудачный пример.

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

В остальных же случаях очень легко схлопотать ошибку, достаточно просто лишний раз нажать на dxButton2. В первое нажатие T будет уничтожено, но так как переменная T не обнулена, то есть ещё содержит ссылку на несуществующий объект, то при повторном нажатии вы будете уничтожать, то чего нет и конечно это будет фиаско ;) .
Destiny is a very convenient word for those who never take decisions.

Аватара пользователя
Гocть
Эксперт
Сообщения: 1586
Зарегистрирован: Пн ноя 27, 2017 8:02 am
Поблагодарили: 9 раз

Re: TStringList

Сообщение Гocть » Чт авг 30, 2018 12:12 pm

Ну или так:

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

procedure FreeObj2(Sender: TObject);
begin
  try
     Sender.Free;
  except
  end;
end;   
Фрилансер. Разработка на заказ. Консультирование.