Why am I not getting an exception if I use the object after it is destroyed?

The following code works great, but it shouldn't! When I click Button1, the object is destroyed first, and then its value is used, and I don't get any access violation or anything else ... Moreover, the multiplication operation gives the correct result, which proves it is Obj1

not destroyed! But then again, this is also not true, because when I close the program it does not report a memory leak. I am 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.

      

+3


source to share


1 answer


The object is destroyed. Memory is returned to the memory manager. What happens next is out of your control. The memory can be returned to the system. In this case, you will see a runtime error. Or the memory can be held in memory by a memory manager ready to be reused the next time the program requests a block of that size. Here's what's going on here.

Your program demonstrates undefined behavior. Anything can happen, including a program that works. Obviously, the program is wrong, and you shouldn't access objects after they have been destroyed.



If you are using the full version of FastMM debug then you should see an error because this scenario takes steps to detect access after the free one. It is a useful debugging tool.

+5


source







All Articles