[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