[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
['{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.
More information about the fpc-pascal
mailing list