给一个我自已的东东参考: unit yy;interface uses Windows, Messages, SysUtils, Forms;function OpenForm(yyForm:TForm):Boolean;implementationfunction OpenForm(yyForm:TForm):Boolean; var i:integer; FormExist:Boolean; begin if yyForm=nil then FormExist:=false else begin FormExist:=false; i:=0; while (i<= Screen.FormCount-1) do begin if Screen.Forms[i].ClassType=yyForm.ClassType then begin FormExist:=true; break; end; i:=i+1; end; end; result:=FormExist; end;end.
我再试试,看能不能通过API函数实现 大家继续指点 我可以再加分
标准做法: if Assigned(对象) then begin 对象.free; 对象:=nil; end;可以用Assigned函数可以判断对象是否创建。但是若一个对象被创建了,而且已经被free掉了, 你用 Assigned(对象) 判断,得到的还是true ,所以要在释放的时候令它为nil ; free时,对象是释放了,但变量的指针还是指在老地方(地址),所以,比需用令它为nil 的方法来斩断指针。
不用再提前 我是这样做的: if (Assigned(MyFormInstance)=false) or (MyFormInstance.ComponentCount=0) then MyFormInstance:=TMyFormInstance.create(application); MyFormInstance.show;
这样可以吗? if form.findcomponent('Edit1') is TEDIT then ... if form.findcomponent('Memo1') is TMemo then ...........
我觉得没有办法,否则Delphi应该会给一个函数,或者Free方法会判断。 但是也还是有解决办法的。第一:如果是FORM的话,你可以从Screen中找看有没有它(Screen.Forms);如果是TControl或TComponent的派生类,应该也可以从Application和Screen.Forms顺滕摸瓜找到; 第二:非常不确切,我似乎从哪本书上看到Delphi有对象管理机制,可能能从这方面入手进行全能的控制; 第三:如果你非要管理,你可以进行自己一套管理机制,如在Form中增加一个List,其中每一项是变量的地址或你的glList,在赋值时往List中加这些东东,然后在FormDestroy中按照List去掉每一个。如: for i:=List.Count-1 downto 0 do begin if IsVarPtr(List[i]) then PTForm(List[i])^ := nil else TList(List[i]).Remove(Self); end; 甚至还可以这样: 每个List中的项都存的是事件处理器: for i:=List.Count-1 downto 0 do TNotifyEvent(List[i])(Self);
首先,应该避免你所描述情况的发生才是上策,在写程序时,若这个指针所指向的对象已经释放掉了,同时应该将该指针置空。 若已经发生了,是不是可以 function IsValid(APointer :Pointer): Boolean; begin Result := True; try 引用一下 except Result := False; end; end;此外,若想知道指向的对象实体是否已经被释放了,需要找些关于Delphi编译的书读,以前听过别人的课,描述了Delphi的内存分配,但现在记不清楚了。大概是一个栈?有时间打开Delphi的system等单元看看(若能看明白)。
if not Assigned(MyFormInstance) then
MyFormInstance:=TMyFormInstance.Create(Application);
我没有表达好,我说的更明白一点就是,DELPHI怎么知道一个指针所指向的对象被释放了
我们能不能做到,是不是释放的内存地址有什么标志
检查该指针指向的地址是否被分配,或者该地址的指定地址的属性是否是该类的属性我就是不知怎么检查,请给指点一下谢谢!
也许用操作系统的API可以知道指向的地址不是被分配了,但是我不知道
释放的内存地址没有什么标志。但是操作系统那边应该有一个可用内存表和分配内存表
unit yy;interface
uses Windows, Messages, SysUtils, Forms;function OpenForm(yyForm:TForm):Boolean;implementationfunction OpenForm(yyForm:TForm):Boolean;
var i:integer;
FormExist:Boolean;
begin
if yyForm=nil then FormExist:=false
else begin
FormExist:=false;
i:=0;
while (i<= Screen.FormCount-1) do
begin
if Screen.Forms[i].ClassType=yyForm.ClassType then
begin
FormExist:=true;
break;
end;
i:=i+1;
end;
end;
result:=FormExist;
end;end.
大家继续指点
我可以再加分
if Assigned(对象) then
begin
对象.free;
对象:=nil;
end;可以用Assigned函数可以判断对象是否创建。但是若一个对象被创建了,而且已经被free掉了,
你用 Assigned(对象) 判断,得到的还是true ,所以要在释放的时候令它为nil ;
free时,对象是释放了,但变量的指针还是指在老地方(地址),所以,比需用令它为nil 的方法来斩断指针。
事情是这样:
如果我把一个对象实体加到一个指针列表里了,然后我释放了这个实体
即使我把这个实体 =NIL,指针类表对应的指针也并不能等于NIL
所以访问时会出错.
vive()说,操作系统那边应该有一个可用内存表和分配内存表,就是这个意思
有没有可能通过API函数看到某个指针的地址被分配了吗?
事情是这样:
如果我把一个对象实体加到一个指针列表里了,然后我释放了这个实体
即使我把这个实体 =NIL,指针类表对应的指针也并不能等于NIL
所以访问时会出错.
vive()说,操作系统那边应该有一个可用内存表和分配内存表,就是这个意思
有没有可能通过API函数看到某个指针的地址被分配了吗?
free的释放较为安全,而destroy则不可取。
我是这样做的:
if (Assigned(MyFormInstance)=false) or (MyFormInstance.ComponentCount=0) then
MyFormInstance:=TMyFormInstance.create(application);
MyFormInstance.show;
比如
glList: TList;
glform: Tform;
procedure ss;
begin
glList.Add(glform);
......
glForm.Free;
glForm := nil;
//此时的glList[0]不是nil
//但是访问这个指针所指的form却会出错
end;
帮忙再看看
最好的方法就是每次释放完了以后将它赋值为nil。
然后以后用Assigned判断。这是一个编程习惯的问题,要养成一个好的编程习惯可以减掉不少麻烦那。
FORM1:=NIL ;
if form.findcomponent('Edit1') is TEDIT then ...
if form.findcomponent('Memo1') is TMemo then ...........
但是也还是有解决办法的。第一:如果是FORM的话,你可以从Screen中找看有没有它(Screen.Forms);如果是TControl或TComponent的派生类,应该也可以从Application和Screen.Forms顺滕摸瓜找到;
第二:非常不确切,我似乎从哪本书上看到Delphi有对象管理机制,可能能从这方面入手进行全能的控制;
第三:如果你非要管理,你可以进行自己一套管理机制,如在Form中增加一个List,其中每一项是变量的地址或你的glList,在赋值时往List中加这些东东,然后在FormDestroy中按照List去掉每一个。如:
for i:=List.Count-1 downto 0 do
begin
if IsVarPtr(List[i]) then
PTForm(List[i])^ := nil
else
TList(List[i]).Remove(Self);
end;
甚至还可以这样:
每个List中的项都存的是事件处理器:
for i:=List.Count-1 downto 0 do
TNotifyEvent(List[i])(Self);
若已经发生了,是不是可以
function IsValid(APointer :Pointer): Boolean;
begin
Result := True;
try
引用一下
except
Result := False;
end;
end;此外,若想知道指向的对象实体是否已经被释放了,需要找些关于Delphi编译的书读,以前听过别人的课,描述了Delphi的内存分配,但现在记不清楚了。大概是一个栈?有时间打开Delphi的system等单元看看(若能看明白)。
同意slx_7(稻草人),其实很简单的问题,用一把异常了就不存在了,最直接
结果才准确吧。如果VCL有自己更高层的内存管理机制,那么只能看它有没有提供类似的函数了。
另外,前面BlueTrees说“即使Delphi释放了,操作系统也不一定真正的回收了,因为”,我想可能是因为运行库的原因,如果不是直接调用Windows API,那么内存的分配
和释放都是通过运行库进行的,它的内部为了效率也可能实现自己的管理机制。