[fpc-pascal] Managed record questions

Ryan Joseph ryan at thealchemistguild.com
Thu Mar 8 09:13:52 CET 2018



> On Mar 8, 2018, at 2:43 PM, Ryan Joseph <ryan at thealchemistguild.com> wrote:
> 
> In many cases I don’t actually need anything on the heap and a record could be used instead but because of limitations on records in Pascal I need a full class. Doing the ARC route is just solving a problem I created by the fact I used a class instead of a record in the first place. c++ solves this by letting you keep the class on the stack or the heap depending on how you want it’s memory managed. That was a superior choice in my opinion but I understand implementing that in Pascal would be a massive overhaul and probably not worth it.

Just an example to illustrate the stupid things we do everyday without realizing it.

TList keeps some memory allocated on the heap (GetMem) and needs to be freed at the end of it’s life cycle. The class itself has an integer and a pointer (6 bytes). In the function we call TList.Create which allocates some memory from the memory manager for the 6 bytes. We add some values to the list and modify it’s internal memory (which is actually dynamic so that’s a good usage) then when the function ends we call free.

Problems:

1) We interface with the memory manager twice here and the 2nd time for a measly 6 bytes which we knew at compile time anyways (dynamic memory manager for static data??).
2) We need to remember to call Free() at the end of the function and take precaution to not exit early and leak memory (maybe even using a goto to break out of nested loops or nested functions, who knows).

Even using an ARC/garbage collecting approach for this is just stupid and a waste of resources. I know I need the TList members on the stack at compile time (integer + pointer) so why am I doing all this dynamic memory management stuff? It’s still important to use a class though because maybe I need inheritance and heap allocation for other use cases.

type
	TList = class
		private
			count: integer;
			data: pointer; // pointer to some memory on heap
		public
			procedure Add (value: pointer);
	end;

procedure MyProc;
var
	list: TList;
begin
	list := TList.Create;
	list.Add(x);
	...
	list.Free;
end;

The more efficient approach would clearly be something like:

procedure MyProc;
var
	list: stack TList; // assume this allocates us on the stack like a record
begin
	list.Clear; // there’s no Create call so init the class some how
	list.Add(x);
	// Free() is called when MyProc goes out of scope
end;

Regards,
	Ryan Joseph




More information about the fpc-pascal mailing list