Allocating memory without a crash

Looking at

static func UnsafeMutableBufferPointer.allocate(capacity count: Int) -> Self

what happens if the allocation fails? Is it an unconditional run-time error (i.e. a crash)? Is there a Standard allocation primitive that returns a Bool or Optional, or throws upon failure? Or even an init? initializer? Foundation is acceptable as a last resort.

malloc still returns optional if you can use that

Yeah, it crashes. But what makes you think this is a risk?

Exhausting a 64-bit address space is not possible in a well functioning program, and if you did the odds that you can recover from it are zero. Also, many parts of Swift heap allocate at runtime and cannot fail (e.g. creating classes, closures, etc.), so recovering from an allocation failure is likely just to lead to another one immediately.

The only sense in which recovering from allocation is useful is if you’re writing code in a 32-bit address space, when you may be able to handle it, but even there the odds of recovery are low in most programs. Crashing on allocation failure is almost always the right choice.

I want to make an infinite sequence/iterator of integers. Normally, it'll keep going until I run out of memory making integers or making the container to make integers. But I want to make benchmarks, and a hard crash would be a pain to deal with, so I want my iterator to return nil once I hit an integer- or container-level memory limit (or integer-level computation limit).

I can limit my integers by switching my generic parameter from BinaryInteger to FixedWidthInteger then turning on my isDone flag once an addition. etc. hits an overflow. I want to do my due diligence and have similar checks for memory allocations (or I might as well use Array).

You’ll have a hard time testing this on a 64-bit machine in any sensible way! You can test this by means of forcing malloc to fail, so I’d begin by hooking malloc and using that as an intervention.

However I really don’t think I’d invest any time in this; it’ll never happen, and it’s unrecoverable if it does.

So I would have the benchmarks stop after a 1000 (or million, etc.) cycles to get consistent results but stay under memory limits. In this case, the practical memory limit would be when virtual memory thrashing would start. (I would still keep the integer type as FixedWidthInteger to watch for overflows.)