Search code examples
delphiobjectfree

Delphi: How to free object created dynamically as a parameter of method


I have method with a parameter as object (sniped code below):

TMyObject=class(TObject)
  constructor Create();
  destructor Destroy();override;
end;

implementation

function doSomething(x:TMyObject):integer;
begin
  //code
end;

procedure test();
var
  w:integer;
begin
  w:=doSomething(TMyObject.Create);
  //here: how to free the created object in line above?
end;

How destroy object created inside of called method doSomething outside of this method?


Solution

  • In order to free the object instance, you need to have a reference to it on which you can call Free().

    Since you are creating the object instance in-place as a parameter, the only reference you will have is the one inside of the doSomething() parameter.

    You either have to Free it inside of doSomething() (which is practice I would not advise doing):

    function doSomething(x: TMyObject): Integer;
    begin
      try
        //code
      finally
        x.Free;
      end;
    end;
    

    Or, you need to create an additional variable in test(), pass it to doSomething(), and then Free it after doSomething() returns:

    procedure test();
    var
      w: Integer;
      o: TMyObject
    begin
      o := TMyObject.Create;
      try
        w := doSomething(o);
      finally
        o.Free;
      end;
    end;
    

    While one may think that using a reference counted object would allow you to create the object in-place and let reference counting free the object, this kind of construction may not work because of the following compiler issue:

    The compiler should keep a hidden reference when passing freshly created object instances directly as const interface parameters

    This is confirmed by a former Embarcadero compiler engineer, Barry Kelly, in a StackOverflow answer:

    Should the compiler hint/warn when passing object instances directly as const interface parameters?