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» фактически освобождает И создает экземпляр, используя парадигму полиморфизма, но здесь это не нужно. Я только хочу отметить, что дизайн должен оставаться прежним.
Теперь вопрос и проблема - почему это происходит и как это исправить? Кажется, «если Назначено (o2)» не подходит.
Что я думаю: отправка указателя на my.o2 освобождает и nil o2, и я пытаюсь это сделать, но я не смог преобразовать указатель на объект в обработчике сообщений, понятия не имел почему.
Кто-нибудь может помочь? Спасибо