1
\$\begingroup\$

I have this code and at the end of it, FastMM shows that there were memory leaks with all the objects of TSinc:

unit sinc_int;

interface

uses
  Classes,
  log_listener_list_int,
  tick_listener_list_int;

type
  ISinc = interface;

  ISincList = interface;

  ISinc = interface ['{53814230-6308-4259-99FF-6054F2C91F9C}']
  function Execute: Boolean;
  function SincList: ISincList;
  function Log: string;
  procedure AddLog(const Texto: string);
  function LogListenerList: ILogListenerList;
  function TickListenerList: ITickListenerList;
  function SincIntervaloMili: Integer;
  function EstaSincronizando: Boolean;
  procedure Start;
  procedure Stop;
  end;

  ISincList = interface ['{F3355798-4584-4DCE-8EBA-3692B14FA132}']
  function Add(const Item: ISinc): Integer;
  function Count: Integer;
  function Get(const Index: Integer): ISinc;
  procedure Put(const Index: Integer; Item: ISinc);
  procedure Remove(const Item: ISinc);
  procedure Clear;
  procedure Start;
  procedure Stop;
  end;

implementation

end.

unit sinc_class;

interface

uses
  sinc_int, log_listener_list_int, tick_listener_list_int, sinc_thread_class;

type
  TSinc = class (TInterfacedObject, ISinc)
  protected
    FLog: string;
    FSincList: ISincList;
    FLogListenerList: ILogListenerList;
    FTickListenerList: ITickListenerList;
    FSincIntervaloMili: Integer;
    FEstaSincronizando: Boolean;
    FThread: TSincThread;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    function Execute: Boolean; virtual; abstract;
    function SincList: ISincList;
    function Log: string; virtual;
    procedure AddLog(const Texto: string);
    function LogListenerList: ILogListenerList;
    function TickListenerList: ITickListenerList;
    function SincIntervaloMili: Integer;
    function EstaSincronizando: Boolean;
    procedure Start;
    procedure Stop;
  end;

implementation

uses
  sinc_list_class,
  log_listener_list_class,
  tick_listener_list_class;

{ TSinc }

procedure TSinc.AddLog(const Texto: string);
begin
  FLogListenerList.AddLog(Texto);
  FLog:=FLog+Texto;
end;

constructor TSinc.Create;
begin
  FSincList:=TSincList.Create;
  FLogListenerList:=TLogListenerList.Create;
  FTickListenerList:=TTickListenerList.Create;
  FEstaSincronizando:=False;
  FThread:=TSincThread.Create(Self);
end;

destructor TSinc.Destroy;
begin
  FSincList.Clear;
  FSincList:=nil;
  FLogListenerList.Clear;
  FLogListenerList:=nil;
  FTickListenerList.Clear;
  FTickListenerList:=nil;
  FThread.Free;
  inherited;
end;

function TSinc.EstaSincronizando: Boolean;
begin
  Result:=FEstaSincronizando;
end;

function TSinc.Log: string;
begin
  Result:=FLog;
end;

function TSinc.LogListenerList: ILogListenerList;
begin
  Result:=FLogListenerList;
end;

function TSinc.SincIntervaloMili: Integer;
begin
  Result:=FSincIntervaloMili;
end;

function TSinc.SincList: ISincList;
begin
  Result:=FSincList;
end;

procedure TSinc.Start;
begin
  FEstaSincronizando:=True;
  FSincList.Start;
  FThread.Resume;
end;

procedure TSinc.Stop;
begin
  FThread.Suspend;
  FSincList.Stop;
  FEstaSincronizando:=False;
end;

function TSinc.TickListenerList: ITickListenerList;
begin
  Result:=FTickListenerList;
end;

end.

And when I do this:

procedure TForm2.btnSinc1Click(Sender: TObject);
begin
  SincTest:=TSincTest.New;
  SincTest:=nil;
end;

It shows that there were memory leaks with the TSincTest class, its lists and even the thread.

\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to Code Review. Please see Checklist for how to write a good Code Review question. Please also clarify if your program runs as expected, minus the memory leaks, or if the memory leaks cause fatal errors/crash of your program. \$\endgroup\$ – Phrancis Feb 29 '16 at 20:07
  • 1
    \$\begingroup\$ @Phrancis Thank you. I'll correct my question with the checklist and the points you made. \$\endgroup\$ – Luiz Carlos M. Jr. Mar 1 '16 at 13:09
  • 1
    \$\begingroup\$ My guess, you declared SincTest : TSincTest instead of SincTest : ISinc, but you don't supply enough information to know for sure. \$\endgroup\$ – Ken Bourassa Mar 17 '16 at 18:08
2
\$\begingroup\$

I suggest to check around TSync as it inherits from TInterfacedObject, which is reference counted, a typical source of memory leak.

\$\endgroup\$
0
\$\begingroup\$

Unless Delphi syntax has changed since I was writing it, this code will not free the memory allocated to these object, just dereference the pointer.

 FSincList.Clear;
 FSincList:=nil;
 FLogListenerList.Clear;
 FLogListenerList:=nil;
 FTickListenerList.Clear;
 FTickListenerList:=nil;

instead of

  FSincList.Clear;
  FSincList:=nil;  

just call

 FSincList.free;

This will free the memory. You can set it to nil also if you wish.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.