Does New as a function return nil or does it still give a runtime error?
If I want to allocate memory, but handle it gracefully if it fails, what are the recommended approaches?
Thanks, Peter.
Peter N Lewis wrote:
Does New as a function return nil or does it still give a runtime error?
Runtime error.
If I want to allocate memory, but handle it gracefully if it fails, what are the recommended approaches?
You could call GetMemPtr directly (with all the drawbacks of using GetMem vs. New, as you know), or install your own allocator (wrapper) which returns `UndocumentedReturnNil' (as, e.g. BPGetMem in the System unit does). As the name indicates, this was really a quick kludge, added to support this BP compatibility unit ...
I don't think we have a really nice way to do it ATM.
Frank
Peter N Lewis wrote:
Does New as a function return nil or does it still give a runtime error?
If I want to allocate memory, but handle it gracefully if it fails, what are the recommended approaches?
The modern way is to raise an exception. Unfortunatly, GPC still do not support exceptions (I have started working on this, but my code ATM is non-working).
Lacking exceptions you can just jump out of memory allocator (if you provide your own) or error handler (IIRC GPC allows you to install custom error handler).
Waldek Hebisch wrote:
Peter N Lewis wrote:
Does New as a function return nil or does it still give a runtime error?
If I want to allocate memory, but handle it gracefully if it fails, what are the recommended approaches?
The modern way is to raise an exception. Unfortunatly, GPC still do not support exceptions (I have started working on this, but my code ATM is non-working).
Lacking exceptions you can just jump out of memory allocator (if you provide your own) or error handler (IIRC GPC allows you to install custom error handler).
You could also trap runtime errors, using `AtExit', or use the `Trap' unit (which does this internally). This comes somewhat closer to exception, though it's not quite the same. Indeed, this may be the best solution available. It's a bit code to write, but it uses `New' and has no disadvantages in this regard.
program Trap2Demo;
uses Trap;
type p = ^t; t = record Next: p; Data: array [1 .. 50000000] of Integer end;
function SafeAllocate = Res: p;
procedure TryAllocate (Trapped: Boolean); begin if Trapped then begin TrappedExitCode := 0; TrappedErrorAddr := nil; Res := nil end else New (Res) end;
begin TrapExec (TryAllocate) end;
var i: Integer; v, w: p;
begin w := nil; for i := 1 to 5 do begin if i > 1 then WriteLn ('Starting again'); repeat v := SafeAllocate; if v <> nil then begin WriteLn ('Allocated v at address ', PtrCard (v)); v^.Next := w; w := v end until v = nil; WriteLn ('Error occurred, continuing'); while w <> nil do begin v := w; w := w^.Next; WriteLn ('Disposing v at address ', PtrCard (v)); Dispose (v) end end end.
Frank