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

Tony Whyman tony.whyman at mccallumwhyman.com
Fri Oct 7 11:49:20 CEST 2016

You seem to be playing around with words. Perhaps I am guilty of sloppy 
English when I say "interface is copied" when meaning "an interface 
reference is copied". However, this does not change the underlying problem.

The problem being referred to is the functionality described here:


under the title "Interface delegation". The word "contained" does not 
appear here. Maybe it should, but it doesn't. If TContainedObject does 
indeed solve the problem then it would be useful to have it documented 
and, if so, for interface delegation using a TInterfacedObject subclass 
to be at least deprecated and may be even barred.

The problem is that this is Rabbit Hole and it needs filling in 
otherwise more will fall down it.

On 07/10/16 10:31, stdreamer wrote:
> 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
>   ['{72D8B44F-5834-425D-AB3A-45785E94E2E4}']
>     function AsString:string;
>   end;
>   IMyInterface = interface
>    ['{5E04F587-E4A0-42A7-850C-74C882BB5958}']
>    procedure DoSomething;
>   end;
>   //tmyvalue can inherit from tContainedobject
>   //for simplification.
>   TMyValue = class(TInterfacedObject, IValue)
>     function AsString:String;
>   end;
>   //IValue must be part of TMyObject not a simple property.
>   TMyObject = class(TInterfacedObject, IMyInterface, IValue)
>   private
>     property MyValue :TMyValue implements IValue;
>   end;
> Τ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.
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

More information about the fpc-pascal mailing list