unit Unit7;
interface
uses Classes;
type
TListener = class(TThread)
procedure Execute; override;
end;
TMyClass = class
o1,o2: Tobject;
procedure FreeMyObject(var obj: TObject);
constructor Create;
destructor Destroy; override;
end;
implementation
uses Windows, SysUtils;
var l: TListener;
my: TMyClass;
procedure TListener.Execute;
var msg:TMsg;
begin
while(GetMessage(msg, Cardinal(-1), 0, 0)) do
if(msg.message=6) then begin
TMyClass(msg.wParam).FreeMyObject(TObject(msg.lParam));
Exit;
end;
end;
constructor TMyClass.Create;
begin
inherited;
o1:=TObject.Create;
o2:=Tobject.Create; // Invalid pointer operation => mem leak
end;
destructor TMyClass.Destroy;
begin
if(Assigned(o1)) then o1.Free;
if(Assigned(o2)) then o2.Free;
inherited;
end;
procedure TMyClass.FreeMyObject(var obj: TObject);
begin
FreeAndNil(obj);
end;
initialization
l:= TListener.Create();
my:=TMyClass.Create;
sleep(1000); //make sure the message loop is set
PostThreadMessage(l.ThreadID, 6, Integer(my), Integer(my.o2));
finalization
l.Free;
my.Free;
end.
我使用消息处理程序来说明我的问题,以便您能够理解。实际设计要复杂得多。函数'FreeMyObject'实际上是使用多态范例来释放和创建实例,但这里不需要。我只想指出设计应该保持不变。
现在的问题和难题是 - 为什么会发生这种情况,以及如何解决它?似乎'if Assigned(o2)'不适用于它。
我所想的是:向my.o2发送一个指针将释放和nil o2,我试图这样做,但我无法在消息处理程序中从指针转换为对象,不知道为什么。
有人可以帮忙吗?谢谢
if Assigned(x) then x.Free;
这个代码模式是不必要的。因为Free方法已经会检查x是否存在,所以只需要简单地使用x.Free;
即可。 - Rudy Velthuis