Tbitmap的 nil 等于free 吗??? 不明白,大侠们快来救我 ( 积分: 200 )

  • 主题发起人 主题发起人 kinsunc
  • 开始时间 开始时间
K

kinsunc

Unregistered / Unconfirmed
GUEST, unregistred user!
我做了个例子(如下):
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
E_image_path: TEdit;
Button1: TButton;
Image1: TImage;
Image2: TImage;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ReportBmp:Tbitmap;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
OpenDialog1: TOpenDialog;
RBmp:TBitmap;
begin
OpenDialog1:=TOpenDialog.Create(nil);
OpenDialog1.Filter:='Bmp图片文件(*.bmp)|*.bmp';
OpenDialog1.DefaultExt:='bmp';
if OpenDialog1.Execute then
begin
RBmp:=TBitmap.Create();
try
RBmp.LoadFromFile(OpenDialog1.FileName);
Image1.Picture.Assign(RBmp);
E_image_path.Text := OpenDialog1.FileName;
finally
RBmp.Free;
end;
end;
OpenDialog1.Destroy;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if FileExists(E_image_path.Text) then
begin
try
ReportBmp.LoadFromFile(E_image_path.Text);
except
ReportBmp:=nil;
end;
end
else
begin
ReportBmp:=nil;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ReportBmp:=Tbitmap.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
ReportBmp.Free;
end;

end.

图片为:bmp,如果 我按Button1 ,打开一个小图,点一次Button2,再清空E_image_path 的text值,点一次Button2。再打开一个小图,点一次Button2,问题就出来了。
不知道为何?
 
我做了个例子(如下):
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
E_image_path: TEdit;
Button1: TButton;
Image1: TImage;
Image2: TImage;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ReportBmp:Tbitmap;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
OpenDialog1: TOpenDialog;
RBmp:TBitmap;
begin
OpenDialog1:=TOpenDialog.Create(nil);
OpenDialog1.Filter:='Bmp图片文件(*.bmp)|*.bmp';
OpenDialog1.DefaultExt:='bmp';
if OpenDialog1.Execute then
begin
RBmp:=TBitmap.Create();
try
RBmp.LoadFromFile(OpenDialog1.FileName);
Image1.Picture.Assign(RBmp);
E_image_path.Text := OpenDialog1.FileName;
finally
RBmp.Free;
end;
end;
OpenDialog1.Destroy;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if FileExists(E_image_path.Text) then
begin
try
ReportBmp.LoadFromFile(E_image_path.Text);
except
ReportBmp:=nil;
end;
end
else
begin
ReportBmp:=nil;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ReportBmp:=Tbitmap.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
ReportBmp.Free;
end;

end.

图片为:bmp,如果 我按Button1 ,打开一个小图,点一次Button2,再清空E_image_path 的text值,点一次Button2。再打开一个小图,点一次Button2,问题就出来了。
不知道为何?
 
self.Image1.Picture.Assign(nil);
 
我没有测试你的代码,但我分析应该是这样:
1。你的窗体创建的时候就创建了ReportBmp,这时对象ReportBmp是存在的
procedure TForm1.FormCreate(Sender: TObject);
begin
ReportBmp:=Tbitmap.Create;
end;
2。第一次按Button1时,打开一个小图,一切顺利,说明Button1中代码没错
并且这里有赋值E_image_path.Text := OpenDialog1.FileName;
3。(第一次)点击Button2时候由于E_image_path.Text有值(就是前一步赋的值),于是
顺利执行ReportBmp.LoadFromFile(E_image_path.Text);
4。“再清空E_image_path 的text值”,这以后E_image_path.Text的值为空,接着
“点一次Button2”,这时执行的是Button2Click里的else语句:
else
begin
ReportBmp:=nil;
end;
把ReportBmp置空(这样做是不安全的,已经将原来的对象内存抛弃,造成了内存泄漏)
5。“再打开一个小图,点一次Button2”,这里你是用Button1Click打开小图的吧,那么
和第2步一样E_image_path.Text := OpenDialog1.FileName;赋了值,接下来点击
Button2,由于E_image_path.Text有值,则执行
if FileExists(E_image_path.Text) then //判断为真,则执行
begin
try
ReportBmp.LoadFromFile(E_image_path.Text); //这里出错,因为
//前面的步骤中ReportBmp已经置为空(nil),再操作就出现访问错误了

>>看看这样分析是否正确<<
 
请问Jonson_sunshine 。我该如何解决此问题。
 
yf168 你说的。我试了一下. 将ReportBmp:=nil; 改为 ReportBmp.Assign(nil); 并不能解决问题。
 
看清楚了 self.Image1.Picture.Assign(nil);
ReportBmp.PicTure.Assign(nil);
 
to 楼主:
不知道你整个程序当中ReportBmp :Tbitmap;的作用到底是什么,为什么判断了文件不存
在时要置为nil(ReportBmp :=nil;)?能说说确切目的吗?
to yf168:
好像TBitmap类里面没有Picture属性吧(ReportBmp:Tbitmap;)?
 
你这样设置变量和释放是错误的
 
在Button2Click事件中完成ReportBmp对象的创建与free就可以了.最后在窗体释放时判断ReportBmp是否创建了没有释放,如果创建了就将他释放.
 
to Jonson_sunshine:
ReportBmp :Tbitmap; 的定义是用来存放一个小图片的变量用。
程序里有多处要用到同一个图片,所以定义全局的变量。在次只为一个例子。当判断文件不存在时,要清空这个变量的值。
to All:
我是不是要在ReportBmp准备变为空时,将其free掉,再创建一次。
 
哦,大概明白了。
你既然当它是全局变量,就要保证创建和销毁的一致性,以便其它地方使用它时不会出错。
类似Button1Click中的RBmp:TBitmap;,使用的时候创建,然后LoadFromFile(),完毕后
free掉。但这个ReportBmp作为全局变量,你可以在FileExists()为真时创建,然后使用,
为假时(文件不存在),free掉,并将其置为空(nil),也就是FreeAndNil(),这样,其他
地方要使用时可通过判断ReportBmp是否为nil(if ReportBmp = nil 或
if assigned(ReportBmp) = true)来执行相关操作。free以后还要使用,则再创建一次。
如果其他地方不使用这个ReportBmp,则ReportBmp只创建一次就可以了,但绝不能直接
nil掉,要么free,要么FreeAndNil()。
 
Free 是释放内存
nil 是释放指针
 
Jonson_sunshine说得很明白了。
 

Similar threads

I
回复
0
查看
593
import
I
I
回复
0
查看
638
import
I
I
回复
0
查看
641
import
I
I
回复
0
查看
794
import
I
后退
顶部