加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 04:16:57 所属栏目:大数据 来源:网络整理
导读:unit Unit7;interfaceuses 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;implementat
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)) 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’实际上是Frees AND使用多态范例创建一个实例,但这不是必需的.我只想指出设计应该保持不变.

现在问题和问题 – 为什么会发生以及如何解决它?似乎’如果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,LPARAM(@my.o2));

你不需要FreeMyObject,你可以直接调用FreeAndNil.而且您不需要在消息中传递实例.

我希望你的真实代码不像这样奇怪!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读