Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-12 Thread Michael Schnell

On 06.09.2017 18:03, Graeme Geldenhuys wrote:

Quite likely. It did all sound awfully familiar. :-)

Is there even a thinkable solution ?

To me the offering of two incompatible kinds of interfaces (not 
regarding the external libraries but the language construct) seems 
rather odd, especially as the language construct is decently usable 
without attaching to an external library. In fact to me it's already off 
to create a language construct based on the dedicated makeup of some 
external library at all. It would be better to have an independent and 
usable language construct that just offers means to optionally attach to 
certain types of libraries.


OTOH, another related construct already discusses multiple times (and 
seemingly offered by Embarcadero) is ref counted "normal" objects. But 
those are known to introduce certain pitfalls, as well.


-Michael

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-07 Thread Sven Barth via fpc-pascal
Am 07.09.2017 03:48 schrieb "Ryan Joseph" :
>
>
> > On Sep 6, 2017, at 10:20 PM, Sven Barth via fpc-pascal <
fpc-pascal@lists.freepascal.org> wrote:
> >
> > You're missing that FHook was declared as IHook, not THook.
> >
>
> In terms of memory why does it matter how it was declared? The memory was
allocated in Create() so the declaration is just relevant for the
assignment of the new memory. Is FPC doing something magic behind the
scenes?

a) since it's an interface it doesn't *have* a Free method
b) COM interfaces are reference counted and the compiler (both Delphi and
FPC) does automatic reference counting with them (that's the purpose of
TInterfacedObject, it calls Free on itself once the reference count reaches
0)

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Marcos Douglas B. Santos
On Wed, Sep 6, 2017 at 10:17 PM, Ryan Joseph  wrote:
>
>> On Sep 6, 2017, at 10:20 PM, Sven Barth via fpc-pascal 
>>  wrote:
>>
>> You're missing that FHook was declared as IHook, not THook.
>>
>
> In terms of memory why does it matter how it was declared? The memory was 
> allocated in Create() so the declaration is just relevant for the assignment 
> of the new memory. Is FPC doing something magic behind the scenes?
>

Because COM interface variables are automatically released.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Ryan Joseph

> On Sep 6, 2017, at 10:20 PM, Sven Barth via fpc-pascal 
>  wrote:
> 
> You're missing that FHook was declared as IHook, not THook.
> 

In terms of memory why does it matter how it was declared? The memory was 
allocated in Create() so the declaration is just relevant for the assignment of 
the new memory. Is FPC doing something magic behind the scenes?

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Graeme Geldenhuys

On 2017-09-06 16:27, Tony Whyman wrote:

Is history repeating itself:


Quite likely. It did all sound awfully familiar. :-)

I've now [finally] added this to my "Personal Programming Notes" archive 
(yes, I actually have such a file). So hopefully now I will not forget 
about the gotcha of memory leaks and reference counted objects.


Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Michael Van Canneyt



On Wed, 6 Sep 2017, Tony Whyman wrote:


Is history repeating itself:

http://lists.freepascal.org/pipermail/fpc-pascal/2016-August/048579.html


Any historian will confirm this :)

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Tony Whyman

Is history repeating itself:

http://lists.freepascal.org/pipermail/fpc-pascal/2016-August/048579.html


On 06/09/17 09:31, Graeme Geldenhuys wrote:

Hi,

Playing with this small sample application to answer another question 
in this mailing list, I noticed the sample application has a memory 
leak. For the life of me I can't see why or how to resolve it.


I tested with FPC 2.6.4, 3.0.2 and 3.0.4-rc1 under 64-bit FreeBSD.

===[ project1.pas ]
program project1;

{$mode objfpc}{$H+}
{$interfaces COM}

type
  IHook = interface
['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}']
procedure DoIt;
  end;

type
  THook = class(TInterfacedObject, IHook)
  private
procedure DoIt;
  end;

  procedure THook.DoIt;
  begin
writeln(ClassName + ' did it');
  end;

type
  TBaseClass = class(TInterfacedObject, IHook)
  private
FHook: IHook;
property Hook: IHook read FHook implements IHook;
  public
constructor Create;
destructor Destroy; override;
  end;

  constructor TBaseClass.Create;
  begin
FHook := THook.Create;  // FPC 2.6.4 reports a memory leak here
  end;

  destructor TBaseClass.Destroy;
  begin
// nothing to do here
  end;


var
  base: IHook;

begin
  base := TBaseClass.Create;
  base.DoIt;
  base := nil; // just to see if it helped with the memory leak - it 
doesn't


end.
==[ end ]==


When I run the program, the output is as follows:

[t1]$ ./project1
THook did it
Heap dump by heaptrc unit
4 memory blocks allocated : 115/120
2 memory blocks freed : 51/56
2 unfreed memory blocks : 64
True heap size : 1114112 (32 used in System startup)
True free heap : 1113696
Should be : 1113760
Call trace for block $00080072F180 size 32
  $00400379 line 35 of project1.lpr
Call trace for block $00080072F0C0 size 32



Personally I always use CORBA style interfaces, never reference 
counted COM style interfaces. So my programs normally don't have this 
issue, and I use interfaces a lot.





Regards,
  Graeme



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Sven Barth via fpc-pascal
Am 06.09.2017 17:03 schrieb "Ryan Joseph" :
>
>
> > On Sep 6, 2017, at 8:03 PM, Graeme Geldenhuys <
mailingli...@geldenhuys.co.uk> wrote:
> >
> > I couldn't call .Free because FHook was a interface reference type of
type IHook, not THook.
>
> But TInterfacedObject is a class isn’t it? Then you call FHook :=
THook.Create; so a I’d expect a Free(). What am I missing?
>
> type
>  THook = class(TInterfacedObject, IHook)
>  private
>procedure DoIt;
>  end;

You're missing that FHook was declared as IHook, not THook.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Ryan Joseph

> On Sep 6, 2017, at 8:03 PM, Graeme Geldenhuys  
> wrote:
> 
> I couldn't call .Free because FHook was a interface reference type of type 
> IHook, not THook.

But TInterfacedObject is a class isn’t it? Then you call FHook := THook.Create; 
so a I’d expect a Free(). What am I missing?

type
 THook = class(TInterfacedObject, IHook)
 private
   procedure DoIt;
 end;

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Graeme Geldenhuys

On 2017-09-06 11:33, Marcos Douglas B. Santos wrote:

You have resolved just by change FHookInstance
as a class, not an Interface, plus using TAggregatedObject too.


Ah yes, that seems to work too. Many thanks for pointing that out.

So here is another implementation that works with NO memory leaks.

[ project1.pas ]
program project1;

{$mode objfpc}{$H+}
{$interfaces COM}

type
  IHook = interface
['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}']
procedure DoIt;
  end;

type
  THook = class(TAggregatedObject, IHook)
  private
procedure DoIt;
  end;

  procedure THook.DoIt;
  begin
writeln(ClassName + ' did it');
  end;

type
  TBaseClass = class(TInterfacedObject, IHook)
  private
FHookInstance: THook;
property Hook: THook read FHookInstance implements IHook;
  public
constructor Create;
destructor Destroy; override;
  end;

  constructor TBaseClass.Create;
  begin
inherited Create;
FHookInstance := THook.Create(self);
  end;

  destructor TBaseClass.Destroy;
  begin
FHookInstance.Free;
inherited Destroy;
  end;


var
  base: IHook;

begin
  base := TBaseClass.Create;
  base.DoIt;

end.
==[ end ]===


Yeah, just as I said Interfaces are an advanced feature of the 
Object Pascal language. Lots of traps!


Bottom line:

NEVER code without enabling memory leak detection!!!  :)


Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Graeme Geldenhuys

On 2017-09-06 10:30, Ryan Joseph wrote:

FHook := THook.Create;

so you need a FHook.Free call? The class is THook = class(TInterfacedObject, 
IHook) right?


I couldn't call .Free because FHook was a interface reference type of 
type IHook, not THook.



Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Marcos Douglas B. Santos
On Wed, Sep 6, 2017 at 6:55 AM, Graeme Geldenhuys <
mailingli...@geldenhuys.co.uk> wrote:

>
> I can't remember ever [while using Delphi] being forced to implement a
> getter method in the "property ... implements..." line, but it seems that
> is the only way it remove memory leaks under FPC. Weird. :-/


You don't need this getter. You have resolved just by change FHookInstance
as a class, not an Interface, plus using TAggregatedObject too.

I wrote an article about it
http://objectpascalprogramming.com/posts/interfaces-delegacao-problemas-solucoes/

(use Google Translator).

Best regards,
Marcos Douglas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Graeme Geldenhuys

On 2017-09-06 10:55, Graeme Geldenhuys wrote:

On 2017-09-06 10:41, Sven Barth via fpc-pascal wrote:

I think THook needs to derive from TAggregatedObject, cause that couples
the reference counting to that of the controlling instance.


That seems to be heading in the right direction, but such a change on
its own doesn't seem to solve the two memory leaks either. I'll test
under Delphi XE which can report memory leaks to see what it does



Testing with Delphi XE - simply by changing THook to descend from 
TAggregatedObject. Under Delphi it also still reports a memory leak.




Either way, modifying the example to use a getter method AND
TAggregatedObject, I managed to get rid of both memory leaks. Here is
the working [memory leak free] code now:


Under Delphi XE, that was the only way to get rid of the memory leaks too.

So it seems for delegation and using "implements" you are forced to use 
a getter method and object variable (not interface reference variable) - 
under both FPC and Delphi. At least they are consistent. ;-)



ps:
  For those that didn't know Since Delphi 2006, add

  ReportMemoryLeaksOnShutdown := True;

  in your *.dpr file to enable memory leak detection.


Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Ryan Joseph

> On Sep 6, 2017, at 4:55 PM, Graeme Geldenhuys  
> wrote:
> 
> Either way, modifying the example to use a getter method AND 
> TAggregatedObject, I managed to get rid of both memory leaks. Here is the 
> working [memory leak free] code now:

Does the original code work if you just add the Free() call? I would expect it 
to leak without that.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Sven Barth via fpc-pascal
Am 06.09.2017 10:31 schrieb "Graeme Geldenhuys" <
mailingli...@geldenhuys.co.uk>:
> type
>   IHook = interface
> ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}']
> procedure DoIt;
>   end;
>
> type
>   THook = class(TInterfacedObject, IHook)
>   private
> procedure DoIt;
>   end;
>
>   procedure THook.DoIt;
>   begin
> writeln(ClassName + ' did it');
>   end;

I think THook needs to derive from TAggregatedObject, cause that couples
the reference counting to that of the controlling instance.
See here:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Implementing_Interfaces

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Graeme Geldenhuys

On 2017-09-06 09:37, Michael Van Canneyt wrote:

type
   TBaseClass = class(TInterfacedObject, IHook)
   private
 FHook: IHook;
 property Hook: IHook read FHook implements IHook;
   public
 constructor Create;
 destructor Destroy; override;
   end;

   constructor TBaseClass.Create;
   begin
 FHook := THook.Create;  // FPC 2.6.4 reports a memory leak here
   end;

   destructor TBaseClass.Destroy;
   begin
 // nothing to do here
   end;

You must free FHook here, because you are keeping a reference to the object,
not the interface.


I changed the destructor to the code shown below. Just so you know, I 
tried this before I posted the message, and it didn't make any 
difference. FHook is a IHook interface reference, not a object 
reference. I can't change it either, otherwise FPC gives me a compiler 
error on the property ... implements...; line.


  destructor TBaseClass.Destroy;
  begin
inherited;
FHook := nil;
  end;

And the program output gives:

[t1]$ ./project1
THook did it
Heap dump by heaptrc unit
4 memory blocks allocated : 115/120
2 memory blocks freed : 51/56
2 unfreed memory blocks : 64
True heap size : 1114112 (32 used in System startup)
True free heap : 1113696
Should be : 1113760
Call trace for block $00080072F180 size 32
  $00400379 line 35 of project1.lpr
Call trace for block $00080072F0C0 size 32


Still 2 memory leaks. :-(

Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Michael Van Canneyt



On Wed, 6 Sep 2017, Graeme Geldenhuys wrote:


Hi,

Playing with this small sample application to answer another question in 
this mailing list, I noticed the sample application has a memory leak. 
For the life of me I can't see why or how to resolve it.


I tested with FPC 2.6.4, 3.0.2 and 3.0.4-rc1 under 64-bit FreeBSD.

===[ project1.pas ]
program project1;

{$mode objfpc}{$H+}
{$interfaces COM}

type
  IHook = interface
['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}']
procedure DoIt;
  end;

type
  THook = class(TInterfacedObject, IHook)
  private
procedure DoIt;
  end;

  procedure THook.DoIt;
  begin
writeln(ClassName + ' did it');
  end;

type
  TBaseClass = class(TInterfacedObject, IHook)
  private
FHook: IHook;
property Hook: IHook read FHook implements IHook;
  public
constructor Create;
destructor Destroy; override;
  end;

  constructor TBaseClass.Create;
  begin
FHook := THook.Create;  // FPC 2.6.4 reports a memory leak here
  end;

  destructor TBaseClass.Destroy;
  begin
// nothing to do here
  end;


You must free FHook here, because you are keeping a reference to the object,
not the interface. And you must call inherited. 
You must always call inherited in the destructor.


Michael.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] Where and Why is there a memory leak?

2017-09-06 Thread Graeme Geldenhuys

Hi,

Playing with this small sample application to answer another question in 
this mailing list, I noticed the sample application has a memory leak. 
For the life of me I can't see why or how to resolve it.


I tested with FPC 2.6.4, 3.0.2 and 3.0.4-rc1 under 64-bit FreeBSD.

===[ project1.pas ]
program project1;

{$mode objfpc}{$H+}
{$interfaces COM}

type
  IHook = interface
['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}']
procedure DoIt;
  end;

type
  THook = class(TInterfacedObject, IHook)
  private
procedure DoIt;
  end;

  procedure THook.DoIt;
  begin
writeln(ClassName + ' did it');
  end;

type
  TBaseClass = class(TInterfacedObject, IHook)
  private
FHook: IHook;
property Hook: IHook read FHook implements IHook;
  public
constructor Create;
destructor Destroy; override;
  end;

  constructor TBaseClass.Create;
  begin
FHook := THook.Create;  // FPC 2.6.4 reports a memory leak here
  end;

  destructor TBaseClass.Destroy;
  begin
// nothing to do here
  end;


var
  base: IHook;

begin
  base := TBaseClass.Create;
  base.DoIt;
  base := nil; // just to see if it helped with the memory leak - it 
doesn't


end.
==[ end ]==


When I run the program, the output is as follows:

[t1]$ ./project1
THook did it
Heap dump by heaptrc unit
4 memory blocks allocated : 115/120
2 memory blocks freed : 51/56
2 unfreed memory blocks : 64
True heap size : 1114112 (32 used in System startup)
True free heap : 1113696
Should be : 1113760
Call trace for block $00080072F180 size 32
  $00400379 line 35 of project1.lpr
Call trace for block $00080072F0C0 size 32



Personally I always use CORBA style interfaces, never reference counted 
COM style interfaces. So my programs normally don't have this issue, and 
I use interfaces a lot.





Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal