3

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. 
1
  • It's because the memory is still valid; you're just writing to memory locations at that point. You might be scribbling over other objects at that point. Commented Jun 25, 2017 at 17:15

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

5 Comments

doesnt assigning NIL to a freed object would help here ?
@GuidoG Assigning NIL to that very reference does not necessarily help because there could be other references.
@GünthertheBeautiful yes I know of the dangling pointer situation, but in the example code of the OP when he would do Obj1 := NIL; after the free that would raise an exception again, right ?
@David I am not sure FastMM can detect that. I see FastMM can detect freed interface references as well as virtual method calls on already destroyed objects. I do not see an option to raise an exception for reading out a simple field. Can you provide the FastMM option?
@GünthertheBeautiful You are probably right, I've likely misremembered what it can do

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.