[fpc-pascal] Freeing memory with exceptions

Michael Van Canneyt michael at freepascal.org
Sun May 21 09:47:15 CEST 2023



On Sun, 21 May 2023, Hairy Pixels via fpc-pascal wrote:

> I've never really used exceptions myself in Pascal (with the exception of breaking out of deeply recursive function calls) so I don't know all the rules.
>
> In this example lets say you call Test() which allocates some memory and
> then calls out to another function in another unit which raises (the
> programmer doesn't know this because FPC doesn't mark the function as
> throwing exceptions).  Now the Test() function will exit early before
> freeing the memory.
>
> What are you supposed to do here?  The only thing I can think of is to
> wrap every function in try..finally which COULD raise an exception but
> that's a huge mess because literally any function could raise.
>
> ====================================
>
> procedure DoThis;
> begin
>  raise Exception.Create('dead');
> end;
>
> procedure Test;
> begin
>  TObject.Create;
>  // call some code in other unit which raise an exception
>  DoThis;
> end;

Your example will leak memory in any case, even if there is no exception,
since you're not freeing the object anywhere..

Assuming the result of A is not used outside of Test, the following is the
only solution:

procedure Test;

var
  A : TObject;
begin
   A:=TObject.Create;
   Try
     // call some code in other unit which raise an exception
     DoThis;
   finally
     A.Free
   end;
end;

You can try to use interfaces, they will be managed by the compiler.

Alternatively, using generics and management operators you can 
create a record that will automatically free the object at the 
end of the procedure.

Michael.


More information about the fpc-pascal mailing list