[fpc-pascal]ReAlloc Question
memsom at interalpha.co.uk
memsom at interalpha.co.uk
Fri May 16 15:25:22 CEST 2003
James,
didn't I send you a revised version of this ages ago... even if you dumped the
whole of it I would have pointed out why not to use Init and Done over Create
and Destroy. I'll tell you one good reason why you may have memory
leaks... 'done' will never get called if you 'free' an instance of TStrings.
That alone will cause a memory leak.
You did see TList too, right? TStringList and TList will do everything you
want, and TObjectList is another good one (if fpc has it implemented.) For 1.1
also look out for TInterfaceList (one of my favourites in Delphi) and there's
also the heavy handed but usefull TThreadList in multithreaded environments ;-)
In fact, looking at your code, your biggest problem is that you missed how the
destructor works in Object Pascal. TObject has a virtual destructor
called 'Destroy' that gets called when you call 'Free'. Calling the destructor
directly is simply wrong. If you are using Turbo Pascal mode, you should be
calling 'dispose( instance, destructor );' and in Object Pascal (Delphi like)
mode it has to be 'instance.free' which will indirectly call the destructor. If
you name your destructor something random and call it directly, it will leak
memory like a sieve.
Also it would be worthwhile take a look how inheritence works. Look, for
example, at the definition of TObject. The destructor is defined as 'destructor
Destroy; virtual;'. The 'virtual' is the clue here. You must 'override' this
method to get things to work propperly!! Your destructor needs to
call 'inherited destructor' to have any chance at not leaking memory.
destructor TStrings.Destroy;
begin
//whatever deallocation
inherited; //also valid : 'inherited Destroy;'
//like 'super' in java
end;
Naming your constructor as Init, whilst not technically incorrect, breaks
naming conventions and will cause you endless problems if you should ever wish
to derrive your class from somewhere else other than TObject. So, once
interfaces come into play in 1.1, you would want to descend from
TInterfacedObject, and not calling the inherited constructor could be a real
problem. Another classic problem is TThread. Try creating a TThread descendent
and overriding the constructor but not calling the inherited version. The
thread never starts ;-) Got caught by that one a few times.
Matt
---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/
More information about the fpc-pascal
mailing list