net*_*boy 5 delphi pointers memory-leaks
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.
Run Code Online (Sandbox Code Playgroud)
我使用消息处理程序来说明我的问题,以便您理解它.真正的设计要复杂得多.函数'FreeMyObject'实际上是Frees AND使用多态范例创建一个实例,但这不是必需的.我只想指出设计应该保持不变.
现在问题和问题 - 为什么会发生以及如何解决它?似乎'如果Assigned(o2)'不适合它.
我的想法:发送一个指向my.o2的指针将自由和nil o2我尝试这样做,但我无法在消息处理程序中从指针转换为对象,不知道为什么.
有人可以伸手吗?谢谢
你有o2两次免费.一旦作为消息的结果和一次来自析构函数.
你认为你打电话o2给nil你,FreeMyObject但你不是.你实际上设置msg.lParam为0.
o2是一个包含对象引用的变量.您传递的值是o2,当您通过值传递时,您无法修改传递其值的变量.所以你需要传递一个引用o2.为此,您需要添加额外的重定向级别并将指针传递给o2,如下所示:
if(msg.message=6) then begin
FreeAndNil(PObject(msg.lParam)^);
Exit;
end;
...
PostThreadMessage(l.ThreadID, 6, 0, LPARAM(@my.o2));
Run Code Online (Sandbox Code Playgroud)
你不需要FreeMyObject,你可以直接打电话FreeAndNil.而且您不需要在消息中传递实例.
我希望你的真实代码不像这样奇怪!;-)