I want to get a random element from 0 to a huge number (2^31).
I tried creating an Array
from such a Range
(so I can use Swift's Array.randomElement
), as done here:
let myArray: [Int64] = [Int64](0...4294967292)
Which compiles, but crashes with:
MyPoject(1569,0x100cc2f40) malloc: can't allocate region mach_vm_map(size=34359738368) failed (error code=3) MyProject(1569,0x100cc2f40) malloc: set a breakpoint in malloc_error_break to debug
Of course, I can write a custom function to create the array, but that smells, especially because the array will be the exact same every time.
Does Swift provide a better solution?
The error message
malloc: can't allocate region mach_vm_map(size=34359738368)
tells that the runtime could not allocate 32GB memory – that is what an array of 4294967292 64-bit integers would require at
let myArray: [Int64] = [Int64](0...4294967292)
But there is no need to create an array for that purpose. As of Swift 4.2 you can simply call
let rnd = Int64.random(in: 0...4294967292)
// or
let rnd = Int64.random(in: 0..<4294967293)
using one of the
static func random(in range: ClosedRange<Self>) -> Self
static func random(in range: Range<Self>) -> Self
methods of the FixedWidthInteger
protocol.
Finally note that 4294967292
is not 2^31 = 2147483648
– if the intention is to create a random number in the range from 0
(inclusive) to 2^31
(exclusive) then
let rnd = Int32.random(in: 0...Int32.max)
would to the trick.