Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Another Memory Leak


This question is answered.


Permlink Replies: 2 - Last Post: Jul 16, 2016 1:43 AM Last Post By: loki loki Threads: [ Previous | Next ]
Gary Wardell

Posts: 241
Registered: 11/13/03
Another Memory Leak  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 15, 2016 2:27 PM
Hi,

So what am I doing wrong?

unit Unit2;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  System.Generics.Collections;
 
type
 
  TInterestItem = class(TControl)
  private
    var
      FName: string;
  end;
 
type
  TInterestList = class(TObject)
  private
    var
      FInterestList: TObjectList<TInterestItem>;
 
  public
    constructor Create; reintroduce; overload;
    destructor Destroy; reintroduce; overload;
  end;
 
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    oMenuList: TInterestList;
 
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.fmx}
 
constructor TInterestList.Create;
begin
  inherited Create;
  FInterestList := TObjectList<TInterestItem>.Create(True);
end;
 
destructor TInterestList.Destroy;
begin
  FInterestList.Free;
  inherited;
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  oMenuList := TInterestList.Create;
end;
 
procedure TForm2.FormDestroy(Sender: TObject);
begin
//  oMenuList.Destroy;
  oMenuList.Free;
end;
 
end.


Running the above code as is I get this.
And the TInterestList destructor is never executed.

---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:
 
 
 
53 - 60 bytes: TObjectList<Unit2.TInterestItem> x 1
 
 
---------------------------
OK   
---------------------------


If I change it to this:

procedure TForm2.FormDestroy(Sender: TObject);
begin
  oMenuList.Destroy;
//  oMenuList.Free;
end;
 


The destructor is executed and no leaks.

So should I be calling Destroy instead of free?

I thought we were supposed to always call Free?

The documentation says:

Use Free to destroy an object. Free automatically calls the destructor if the object reference is not nil. Any object
instantiated at run time that does not have an owner should be destroyed by a call to Free, so that it can be properly
disposed of and its memory released.


Gary
Delphi Seattle XE10, FireMonkey
Clement Doss

Posts: 76
Registered: 3/26/00
Re: Another Memory Leak
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 15, 2016 2:40 PM   in response to: Gary Wardell in response to: Gary Wardell
Hi,

I would have declared TInterestList class as :

 type
   TInterestList = class(TObject)
   private
       FInterestList: TObjectList<TInterestItem>;
   public
     constructor Create;
     destructor Destroy;  override;
   end;

and the implementation as :

 constructor TInterestList.Create;
 begin
   FInterestList := TObjectList<TInterestItem>.Create(True);
 end;
 
 destructor TInterestList.Destroy;
 begin
   FInterestList.Free;
   inherited;
 end;


This way the code works as expected.

HTH,
Clément

Gary Wardell wrote:
Hi,

So what am I doing wrong?

unit Unit2;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  System.Generics.Collections;
 
type
 
  TInterestItem = class(TControl)
  private
    var
      FName: string;
  end;
 
type
  TInterestList = class(TObject)
  private
    var
      FInterestList: TObjectList<TInterestItem>;
 
  public
    constructor Create; reintroduce; overload;
    destructor Destroy; reintroduce; overload;
  end;
 
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    oMenuList: TInterestList;
 
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.fmx}
 
constructor TInterestList.Create;
begin
  inherited Create;
  FInterestList := TObjectList<TInterestItem>.Create(True);
end;
 
destructor TInterestList.Destroy;
begin
  FInterestList.Free;
  inherited;
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  oMenuList := TInterestList.Create;
end;
 
procedure TForm2.FormDestroy(Sender: TObject);
begin
//  oMenuList.Destroy;
  oMenuList.Free;
end;
 
end.


Running the above code as is I get this.
And the TInterestList destructor is never executed.

---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:
 
 
 
53 - 60 bytes: TObjectList<Unit2.TInterestItem> x 1
 
 
---------------------------
OK   
---------------------------


If I change it to this:

procedure TForm2.FormDestroy(Sender: TObject);
begin
  oMenuList.Destroy;
//  oMenuList.Free;
end;
 


The destructor is executed and no leaks.

So should I be calling Destroy instead of free?

I thought we were supposed to always call Free?

The documentation says:

Use Free to destroy an object. Free automatically calls the destructor if the object reference is not nil. Any object
instantiated at run time that does not have an owner should be destroyed by a call to Free, so that it can be properly
disposed of and its memory released.


Gary
Delphi Seattle XE10, FireMonkey
loki loki

Posts: 787
Registered: 7/1/02
Re: Another Memory Leak [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 16, 2016 1:43 AM   in response to: Gary Wardell in response to: Gary Wardell
type
TInterestList = class(TObject)
private
var
FInterestList: TObjectList<TInterestItem>;

public
constructor Create; reintroduce; overload;
destructor Destroy; reintroduce; overload;
end;

what the purpose to make destroy as reintroduce? of course it's will be
never call by free now (you reintroduce it in TInterestList)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02