gpt4 book ai didi

delphi - 为什么会出现内存泄漏以及如何修复它?

转载 作者:行者123 更新时间:2023-12-03 15:07:15 30 4
gpt4 key购买 nike

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,我尝试这样做,但我无法在消息处理程序中从指针转换为对象,不知道为什么。

有人可以帮忙吗?谢谢

最佳答案

您释放了 o2 两次。一次作为消息的结果,一次来自析构函数。

当您调用 FreeMyObject 时,您认为将 o2 设置为 nil,但事实并非如此。实际上,您将 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));

不需要FreeMyObject,直接调用FreeAndNil即可。并且您不需要在消息中传递实例。

我希望你真正的代码没有这么奇怪! ;-)

关于delphi - 为什么会出现内存泄漏以及如何修复它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6974294/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com