I have a piece of Delphi code
var
a: array of array of array of integer;
begin
try
SetLength(a, 100000, 100000, 10000); // out of memory here
doStuffs(a);
except
a = nil; // try to free the memory
end;
end;
The above code tries to allocate lots of memory and out-of-memory will be caught. The a=nil will be executed, but the memory isn’t freed.
Is there a way to free the memory in the case of out-of-memory exception?
I tried SetLength(a, 0, 0, 0) and Finalize(a), and both won’t work either.
In general, it’s not possible to recover from an out of memory error. At that point the heap is most likely corrupted. The appropriate response is to terminate the process.
In this specific case, the allocation is performed by
DynArraySetLengthin theSystemunit. This performs repeated allocations. Only as the last act ofDynArraySetLengthis the return value,ain your code above, actually assigned. And if errors occur inDynArraySetLengththen the runtime makes no effort to tidy up. Which means that in case of failure, any memory allocated is leaked and cannot be recovered. You have no way to refer to it in order to free it.You may think that
DynArraySetLengthshould do more to tidy up. However, it’s approach is justifiable. Since out of memory conditions invariably result in corrupt heap, attempts to tidy up would just prolong the agony. Once the heap is dead, there’s no point in trying to deallocate memory.