Reputation: 3120
The following code works just fine, but it shouldn't ! When I click the Button1, the object is destroyed first, and then its Value is used and I don't receive any Access Violation or something... Even more, the multiply operation gives the correct result, that proves that Obj1
is not destroyed ! But then again, this is not true either, because when I close the program it does'n report any memory leakage. I'm very confused.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
MyObj = class(TObject)
Value: Cardinal;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
public
Obj1:MyObj;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Obj1.Free;
Obj1.Value:=Obj1.Value * 5;
Caption:=IntToStr(Obj1.Value);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown:=true;
Obj1:=MyObj.Create;
Obj1.Value:=10;
end;
end.
Upvotes: 3
Views: 197
Reputation: 613441
The object is destroyed. The memory is returned to the memory manager. What happens next is out of your control. The memory could be returned to the system. In which case you'd see a runtime error. Or, the memory could be kept alive by the memory manager ready to reuse the next time the program asks for a block of that size. This is what happens here.
Your program exhibits undefined behaviour. Anything could happen, including the program appearing to work. Obviously the program is wrong and you must not access objects after they have been destroyed.
If you use the full debug version of FastMM then you should see an error because in that scenario steps are taken to detect access after free. That's a useful debugging tool.
Upvotes: 5