Search code examples
swiftlargenumberrandom-seedint64

malloc error when generating huge random number


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?


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.