[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