[fpc-pascal] Management operators question

Ryan Joseph ryan at thealchemistguild.com
Sat May 26 03:22:45 CEST 2018



> On May 25, 2018, at 7:03 PM, Maciej Izak <hnb.code at 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




More information about the fpc-pascal mailing list