开发者

Calling aControl.free inside aControl

After reading this I would like to know what is the pro开发者_JAVA百科blem with the next code:


procedure TForm1.Button5Click(Sender: TObject);
begin
  Button5.free;
end;


Put a breakpoint on that routine and examine the call stack. Once you return from the event handler, there's still code from Button5 running, and other VCL code that expects Button5 to still be around. If you delete the object out from under it, there's a good chance that you'll end up corrupting memory or raising exceptions somehow.

If you want to do this, the correct way is to call PostMessage and post a message to the form that will end up freeing the object safely after the current code is finished running.


The code is a worst kind of a bug because it does not reveal itself in 99.99% of cases. You free an object (button control) while VCL assumes the object exists. What actually happen is that the object's memory is freed, but not reused yet, so the above code will work OK, as if the object was not freed yet, but still it is a bug.

The following simple bug illustrates the situation:

type
  PData = ^TData;
  TData = record
    Value: Integer;
  end;

procedure NastyBug;
var
  P: PData;

begin
  New(P);
  P^.Value:= 2;
  Dispose(P);
// nasty buggy code
  ShowMessage(IntToStr(P^.Value));
  P^.Value:= 22;
  ShowMessage(IntToStr(P^.Value));
end;

You can test the above code and it should work as expected, because the disposed memory for P is not reused yet, but the code is a clear bug.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜