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.
Tôi đã sử dụng trình xử lý tin nhắn để minh họa cho vấn đề của mình như vậy là bạn hiểu nó. Thiết kế thực sự phức tạp hơn rất nhiều. Chức năng 'FreeMyObject' thực sự giải phóng và tạo ra một thể hiện bằng cách sử dụng mô hình đa hình, nhưng điều này ở đây là không cần thiết. Tôi chỉ muốn chỉ ra rằng thiết kế nên giữ nguyên.Tại sao có rò rỉ mem và cách khắc phục?
Bây giờ câu hỏi và vấn đề - tại sao nó xảy ra và cách khắc phục? Có vẻ như 'nếu được gán (o2)' không phù hợp với nó.
Điều tôi nghĩ: Gửi con trỏ tới my.o2 sẽ miễn phí và không o2 và tôi cố gắng làm như vậy, nhưng tôi không thể chuyển đổi từ con trỏ sang đối tượng trong trình xử lý thư, không biết tại sao.
Ai đó có thể trao tay không? Cảm ơn
Liệu 'hoạt động con trỏ không hợp lệ => mem leak' thực sự thuộc về dòng 'o2: = Tobject.Create; ' – mjn
@mjn. Nó có thể thuộc về dòng tương ứng trong destructor. :) – GolezTrol
Bạn nên sử dụng giá trị cao hơn WM_APP cho số thư. 6 là WM_ACTIVATE và có thể gây ra sự cố. – GolezTrol