![]() |
| ||
|
|
Новости |
Поиск |
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 ситуация не менялась.
Ega23 (2008-04-23 12:36:00) [641]
> Сам попался? :)
С некоторых пор, если есть вероятность того, что в конструкторе raise встретится, предпочитаю сначала nil приравнять... :)
Рамиль (2008-04-23 12:34:00) [642]
> Ega23 © (23.04.08 12:32) [10]
Сам попался? :)
Ega23 (2008-04-23 12:32:00) [643]
> ха... если бы он был равен Nil.. он не равен Nil, Nil для
> Free несмертелен, TempBitmap будет неинициализирован то
> бишь мусор, а вот это для Free уже критично
>
Согласен, неточно выразился.
Ega23 (2008-04-23 12:30:00) [644]
> Если в конструкторе будет ошибка то в секцию финал мы не
> попадем вовсе...
>
Да ну????
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyObj = class
public
constructor Create(const RaiseException : Boolean = False);
procedure DoWork;
end;
TForm2 = class(TForm)
Button1: TButton;
Label1: TLabel;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
{ TMyObj }
constructor TMyObj.Create(const RaiseException: Boolean);
begin
if RaiseException then
raise Exception.Create('TMyObj.Create');
end;
procedure TMyObj.DoWork;
begin
ShowMessage('TMyObj.DoWork');
end;
procedure TForm2.Button1Click(Sender: TObject);
var
obj : TMyObj;
begin
Label1.Caption := '';
obj := TMyObj.Create(True);
try
obj.DoWork;
finally
Label1.Caption := 'попали в finally';
obj.Free;
end;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
obj : TMyObj;
begin
Label1.Caption := '';
try
obj := TMyObj.Create(True);
obj.DoWork;
finally
Label1.Caption := 'попали в finally';
obj.Free;
end;
end;
end.
Palladin (2008-04-23 12:25:00) [645]
> Ega23 © (23.04.08 12:21) [3]
> то TempBitmap будет равен nil. А после ты попадаешь на finally,
> где вызываешь free.
ха... если бы он был равен Nil.. он не равен Nil, Nil для Free несмертелен, TempBitmap будет неинициализированто бишь мусор, а вот это для Free уже критично
{RASkov} (2008-04-23 12:24:00) [646]> [6] {RASkov} © (23.04.08 12:23)
.... это если использовать код из [1]
{RASkov} (2008-04-23 12:23:00) [647]> Потому что если в конструкторе произойдёт исключение, то
> TempBitmap будет равен nil. А после ты попадаешь на finally,
> где вызываешь free.
Если в конструкторе будет ошибка то в секцию финал мы не попадем вовсе...
{RASkov} (2008-04-23 12:22:00) [648]> но непонятно... почему варнинг?
Потому как создание объекта в защищенной секции, а уничтожение принудительное в финале.... поэтому компилятор и говорит, что объект может и не создасться и в финале будет АВ.
Решение в [1]... т.е. создание вынести из защитного блока...
{RASkov} (2008-04-23 12:22:00) [649]:)
Arinyshka (2008-04-23 12:21:00) [650]упс :) чувствую себя дура дурой :) Ну конечно! спасибо :)))))
Ega23 (2008-04-23 12:21:00) [651]
> Не смертельно, но непонятно... почему варнинг?
Потому что если в конструкторе произойдёт исключение, то TempBitmap будет равен nil. А после ты попадаешь на finally, где вызываешь free.
Create нужно выносить за блок try..finally
Рамиль (2008-04-23 12:18:00) [652]
TempBitmap := TBitmap.Create;
try
TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;