THSoftPoland
THSoftPoland

Reputation: 13

Delphi: Why does this generate a memory leak?

Why is TDemo.TBuilder is not automatically freed and producing a memory leak ? TDemo.TBuilder should be freed automatically, as this is a TInterfacedObject object based on IInterface

type
  TDemo = class
    public type
      TBuilder = class(TInterfacedObject)
        public
          function Generate: TDemo;
      end;
    public
      class procedure Using;
  end;

implementation

function TDemo.TBuilder.Generate: TDemo;
begin
  Result := TDemo.Create;
  // on finish this method, TDemo.TBuilder should be freed ! 
end;

class procedure TDemo.Using;
begin
  with TDemo.TBuilder.Create.Generate do try
    // use TDemo
    
  finally
    Free;
  end;
end;

Upvotes: 1

Views: 292

Answers (1)

Dalija Prasnikar
Dalija Prasnikar

Reputation: 28517

You have memory leak because TBuilder.Create returns object reference and since it is used as intermediate reference in with call it was never assigned to interface reference and its reference counting mechanism was never properly initialized.

To solve this, you need to declare IBuilder interface and use class function returning that interface for constructing such intermediate object.

  TDemo = class
  public type
    IBuilder = interface
      function Generate: TDemo;
    end;

    TBuilder = class(TInterfacedObject, IBuilder)
    public
      function Generate: TDemo;
      class function New: IBuilder;
    end;
  public
    class procedure Using;
  end;


class function TDemo.TBuilder.New: IBuilder;
begin
  Result := TBuilder.Create;
end;

  with TDemo.TBuilder.New.Generate do
  ... 

Upvotes: 6

Related Questions