Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?


2 Answers

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.

like image 110
Martin R Avatar answered Dec 10 '25 06:12

Martin R


ClosedRange also has a randomElement method in Swift 4.2:

print((0...4294967292).randomElement()!)

Note that you said you want a random number between 0 and 2^31, but you used 1...4294967292 instead of 0...4294967292 in your example.

like image 28
Sweeper Avatar answered Dec 10 '25 04:12

Sweeper