> On May 25, 2018, at 7:03 PM, Maciej Izak <hnb.c...@gmail.com> wrote:
> 
> all is balanced :) you forgot to handle operator :
> 
> class operator Copy(constref src: TDynArray<T>; var dest: TDynArray<T>);
>  
> and 
> 
> class operator AddRef(var a: TDynArray<T>);
> 
> for the line from example "d := TIntArray.Create([1, 2, 3]);" the "Copy" 
> operator is executed (you need to check when which operator is used - this is 
> the best way to learn, on the beginning it may looks a bit complicated): so 
> for each AddRef, Copy and Initialization the Finalization operator is 
> executed.
> 

I expanded the example but there’s still one thing I don’t get. How can it be 
that Initialize/Finalize are called in a pair then push is called directly 
after? I expected Finalize to be the final call before the the object is out of 
scope and not usable anymore. If I was keeping reference counts I would already 
be at 0 when the first push call was made.


init 00007FFEEFBFF828
dealloc 00007FFEEFBFF828
push 1 to 00007FFEEFBFF828 <—— here’s where I’m confused

type
        generic TDynArray<T> = record
                private type TDynArrayTable = array[0..0] of T;
                private type TDynArrayTablePtr = ^TDynArrayTable;
                private
                        table: TDynArrayTablePtr;
                public
                        constructor Create (values: array of T);
                        procedure Push(value: T);
                        class operator Finalize(var a: TDynArray);
                        class operator Initialize(var a: TDynArray);
                        class operator AddRef(var a: TDynArray);
                        class operator Copy(constref aSrc: TDynArray; var aDst: 
TDynArray);
        end;

constructor TDynArray.Create (values: array of T);
var
        value: T;
begin
        for value in values do
                Push(value);
end;

class operator TDynArray.AddRef(var a: TDynArray);
begin
        writeln('addref');
end;

class operator TDynArray.Copy(constref aSrc: TDynArray; var aDst: TDynArray);
begin
        writeln('copy ', HexStr(@aSrc), ' to ', HexStr(@aDst));
end;

class operator TDynArray.Initialize(var a: TDynArray);
begin
        writeln('init ', HexStr(@a));
        a.table := nil;
end;

class operator TDynArray.Finalize(var a: TDynArray);
begin
        if a.table <> nil then
                begin
                        FreeMem(a.table);
                        writeln('free');
                        a.table := nil;
                end;
        writeln('dealloc ', HexStr(@a));
end;

procedure TDynArray.Push(value: T);
begin
        if table = nil then
                table := GetMem(0);
        writeln('push ', value, ' to ', HexStr(@self)); // grow array etc...
end;

procedure TestDynArray;
type
        TIntArray = specialize TDynArray<Integer>;
var
        d: TIntArray;
begin
        d := TIntArray.Create([1, 2, 3]);
        d.Push(100);
end;

init 00007FFEEFBFF7C0
init 00007FFEEFBFF828
dealloc 00007FFEEFBFF828
push 1 to 00007FFEEFBFF828
push 2 to 00007FFEEFBFF828
push 3 to 00007FFEEFBFF828
copy 00007FFEEFBFF828 to 00007FFEEFBFF7C0
push 100 to 00007FFEEFBFF7C0
free
dealloc 00007FFEEFBFF828
free
dealloc 00007FFEEFBFF7C0


Regards,
        Ryan Joseph

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

Reply via email to