[fpc-pascal] A serious Memleak using delegates/implements (was: Delegate Interface class does not seem to be referenced counted)

stdreamer stdreamer at freemail.gr
Fri Oct 7 11:31:03 CEST 2016

On 05/10/2016 19:13 μμ, Tony Whyman wrote:
> Marcos,
> I believe I concluded that this could be a bug or feature. Either way it
> is a Bear Trap waiting for the unwary programmer and it would be nice if
> in some way the implementation could be improved. The problem, as I see
> it is:
> Basics:
> 1. Whenever an interface reference is coerced from an interfaced object,
> the object's reference count is incremented.
I'm guessing that by "coerced" you mean "reference a contained interface".

> 2. When the interface is copied that reference count is again incremented.
Interface can not be copied only implement objects can be copied and 
when they are their interface counter has nothing to do with the 
original interface, in fact it is the exact opposite, after a copy you 
need to make sure that the counter has been reset, which leads to 
believe that I misunderstood something.

> 3. When the interface goes out of scope, the reference count is
> decremented and when it reaches zero, the object is freed.
> So far so good, but, when you have a delegated interface:
> Terminalogy: In the example:
>      TMyValue = class(TInterfacedObject,IValue);
>      TMyObject = class (TinterfacedObject,IMyInterface)
>      ...
>      property Value: IValue read FValue implements IValue;
>      end;
>      Then a TMyValue object "is the source of" the delegated interface.
>      A TMyObject object "provides" the delegated interface.

That is not a delegated interface that is a contained interface.

A delegated interface goes something like this

   IValue = interface
     function AsString:string;

   IMyInterface = interface
    procedure DoSomething;

   //tmyvalue can inherit from tContainedobject
   //for simplification.
   TMyValue = class(TInterfacedObject, IValue)
     function AsString:String;
   //IValue must be part of TMyObject not a simple property.
   TMyObject = class(TInterfacedObject, IMyInterface, IValue)
     property MyValue :TMyValue implements IValue;

Τhe problem of a contained interface has already been solved, see the 
TContainedObject. To sum it up a contained object reference counting 
mechanism increments and decrements the container's reference counter it 
does not have a life of its own.

Sorry the rest look like a rabbit hole based on the wrong assumptions to 
me, there might be some merit but I have no will to search for it.

More information about the fpc-pascal mailing list