![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Освобождение ресурса в finally
Arinyshka © (2008-04-23 12:17:00)
Страницы: < 1 2 ... 24 25 26 27 28 29 30 31 32 33 >
Не подскажете еще один момент:
Есть процедура, выглядит примерно так
procedure TSetPayFrm.BtnAddImageClick(Sender: TObject);
var TempBitmap:TBitmap;
begin
if not(opendialog1.Execute) then exit;
try
TempBitmap := TBitmap.Create;
TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;
end;
На освобождение TempBitmap.Free; выдает варнинг
[Warning] uSetPaymentMain.pas(313): Variable 'TempBitmap' might not have been initialized
Не смертельно, но непонятно... почему варнинг? При изменениии условия и включении всей конструкции в один блок begin..end ситуация не менялась.
ZENsan (2008-04-24 11:52:00) [601]Полностйу соглаес с АНБ
ANB (2008-04-24 11:52:00) [602]
>
> {RASkov} © (24.04.08 11:39) [46]
> > [45] ZENsan © (24.04.08 11:34)
>
> А смысл? не вижу...(
> Но если еще и коструктор(ы) в защитный блок затащить, так
> еще и хинтов/варнингов от компилятора "слушать"...) Зачем?
>
> И еще.... и даже с одним блоком финали мы не лишены возможности
> два раза освободить объект :)
Ни хинтов не варнингов при таком способе нету.
ANB (2008-04-24 11:51:00) [603]
> Ega23 © (24.04.08 10:58) [39]
>
> > Затем, что ошибка может настичь и на Obj5 := TObj.Create;
>
> > где же тогда освобождать Obj1 … Obj5
>
>
> А в таком случае надо по-хорошему так:
>
> Obj1 := TObj.Create;
> try
> Obj2 := TObj.Create;
> try
> Obj3 := TObj.Create;
> try
> .......
> finally
> Obj3.Free;
> end;
> finally
> Obj2.Free;
> end;
> finally
> Obj1.Free;
> end;
> <Цитата>
Извращение и плохо читаемо.
ZENsan (2008-04-24 11:51:00) [604]Не факт. Смотри:
Obj1:=TObj.Create;
if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;
Ну а такой код-то от чего появился вдруг?
if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;
Конечно тут ошибка будет
{RASkov} (2008-04-24 11:48:00) [605]> [47] ZENsan © (24.04.08 11:43)
> Там обйектам нил присваивался перед блоком Трай.. Какие варнинги..
Такой код появляется скорее из-за лени программиста нежели из-за профессианализма)
И для других может выглядеть запутанно :(
ZENsan (2008-04-24 11:43:00) [606]Там обйектам нил присваивался перед блоком Трай.. Какие варнинги..
А если мы конструкторы в незащищённый блок поставим... то смотри:
Obj1 := TObj1.Create();{сработал, память выделилась}
Obj2 := TObj2.Create();{исключение}
try
...
finally
...
end;
Memory leak..
{RASkov} (2008-04-24 11:39:00) [607]> [45] ZENsan © (24.04.08 11:34)
А смысл? не вижу...(
Но если еще и коструктор(ы) в защитный блок затащить, так еще и хинтов/варнингов от компилятора "слушать"...) Зачем?
И еще.... и даже с одним блоком финали мы не лишены возможности два раза освободить объект :)
ZENsan (2008-04-24 11:34:00) [608]Ну ето понятноъъъ Но мы же вроде про один блок Try Finally...
Там тогда просто надо:
If Assigned(Obj1) then
FreaAndNil(Obj1);
{RASkov} (2008-04-24 11:33:00) [609]> [42] Arinyshka (24.04.08 11:28)
> f Assigned(Obj1) then
> Obj1.Free;i
> тогда я никого не попытаюсь освободить дважды
Не факт. Смотри:
Obj1:=TObj.Create;
f Assigned(Obj1) then Obj1.Free;
f Assigned(Obj1) then Obj1.Free;
И тут АВ на второй строке.
Правильно так:
Obj1:=TObj.Create;
f Assigned(Obj1) then begin Obj1.Free; Obj1:=nil; end;
f Assigned(Obj1) then begin Obj1.Free; Obj1:=nil; end; //не будет АВ
ну или Freeandnil()...
ZENsan (2008-04-24 11:31:00) [610]Да делай именно так Аринишка - стандартный подход. Можно конечно и в секциях - так лучше если ты используеш этот код очень часто (не будешь каждый раз создавать и удалять объект..)
Arinyshka (2008-04-24 11:28:00) [611]А мне велено почитать про секцию finalization. Может, так действительно проще?
инициализировать и освободить в соотв секциях...
Из советов мне понятен вариант с проверкой:
f Assigned(Obj1) theni
Obj1.Free;
тогда я никого не попытаюсь освободить дважды
ZENsan (2008-04-24 11:16:00) [612]Удалено модератором
{RASkov} (2008-04-24 10:59:00) [613]> [36] ANB (24.04.08 10:31)
> это написать и корректно и читабельно ?
Obj1 := TObj.Create;
try
Obj2 := TObj.Create;
try
Obj3 := TObj.Create;
try
Obj4 := TObj.Create;
try
Obj5 := TObj.Create;
try
...
работа с объектами и куча другого кода
finally
FreeAndNil(Obj5);
end;
finally
FreeAndNil(Obj4);
end;
finally
FreeAndNil(Obj3);
end;
finally
FreeAndNil(Obj2);
end;
finally
FreeAndNil(Obj1);
end;
или при уверенности, что в конструкторе не будет ошибок, то:
Obj1 := TObj.Create;
Obj2 := TObj.Create;
Obj3 := TObj.Create;
Obj4 := TObj.Create;
Obj5 := TObj.Create;
try
...
работа с объектами и куча другого кода
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
FreeAndNil(Obj3);
FreeAndNil(Obj4);
FreeAndNil(Obj5);
end;
Но если честно, то у меня такого в коде никогда еще не встречалось :)
Ega23 (2008-04-24 10:58:00) [614]
> Затем, что ошибка может настичь и на Obj5 := TObj.Create;
> где же тогда освобождать Obj1 … Obj5
А в таком случае надо по-хорошему так:
Obj1 := TObj.Create;
try
Obj2 := TObj.Create;
try
Obj3 := TObj.Create;
try
.......
finally
Obj3.Free;
end;
finally
Obj2.Free;
end;
finally
Obj1.Free;
end;
ЮЮ (2008-04-24 10:51:00) [615]> Зачем создание внутрь try тащить???
Затем, что ошибка может настичь и на Obj5 := TObj.Create; где же тогда освобождать Obj1 Obj5
P/s/ Нафига только такими объектами пользоваться, которые ломаются уже в конструкторе. :)
В реальной жизни так печься только о TFileStream-e приходилось
Ega23 (2008-04-24 10:35:00) [616]
> ANB (24.04.08 10:31) [36]
Зачем создание внутрь try тащить???
ANB (2008-04-24 10:31:00) [617]Игорь Шевченко © (23.04.08 23:04) [35]
В случае с одним объектом, конечно, доп.строки являются лишними.
Это я по привычке пишу, чтобы потом не переделывать, если в процедуре понядобятся еще объекты.
Однако рассмотрим код :
Obj1 := nil;
Obj2 := nil;
Obj3 := nil;
Obj4 := nil;
Obj5 := nil;
try
Obj1 := TObj.Create;
Obj2 := TObj.Create;
Obj3 := TObj.Create;
Obj4 := TObj.Create;
Obj5 := TObj.Create;
...
работа с объектами и куча другого кода
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
FreeAndNil(Obj3);
FreeAndNil(Obj4);
FreeAndNil(Obj5);
end;
Как без начального зануливания переменных под объекты это написать и корректно и читабельно ?
ЗЫ. Большуюя часть тактов процессора нынче съедают не наши приложения а рисование рюшечек операционки. Да и рюшечек наших приложений частенько тоже.
Игорь Шевченко (2008-04-23 23:04:00) [618]ANB (23.04.08 16:31) [31]
И эта...я понимаю, что локальные переменные обнулять после использования это конечно безусловно кошерно, но такты процессора являются тоже ресурсом и их следует расходовать экономно, что бы там раввин не говорил...
Игорь Шевченко (2008-04-23 23:02:00) [619]ANB (23.04.08 13:40) [22]
> Читать сомневающимся до полного просветления.
Прочитал, не просветлился. Автор безусловно человек уважаемый, но к чему писать лишние строки, я так и не понял. Их и без того хватает, чтобы запутаться, мусорить нехорошо.
Loginov Dmitry (2008-04-23 22:43:00) [620]http://matrix.kladovka.net.ru/index.php?page=tryfinally