I have a challenge with a variable with type UnsafeMutablePointer<UInt8>
.
I have this working code to alloc and set to zero all an UInt8
array in Swift.var bits = UnsafeMutablePointer<UInt8>(calloc(width * height, 8))
The problem is I'd like to do it without use the calloc method. I have this code to alloc the arrayvar bits = UnsafeMutablePointer<UInt8>.alloc(width * height)
but I can't find a method to set to zero all the memory.
I know I can do this, but I don't think is the best way.
for index in 0..< (width * height) {
bits[index] = 0
}
As @matt suggests, you can use initializeFrom
to initialize the memory. I would use the Repeat
collection type for this, as it avoids any interim allocation:
var bits = UnsafeMutablePointer<UInt8>.alloc(width * height)
bits.initializeFrom(Repeat(count: width * height, repeatedValue: 0))
(note, there’s no need to give the type of the value to Repeat
, it can be inferred from the type of bits
)
If you find you do this a lot, it might be worth creating a calloc
-like extension to UnsafeMutablePointer
:
extension UnsafeMutablePointer {
// version that takes any kind of type for initial value
static func calloc(num: Int, initialValue: T) -> UnsafeMutablePointer<T> {
let ptr = UnsafeMutablePointer<T>.alloc(num)
ptr.initializeFrom(Repeat(count: num, repeatedValue: initialValue))
return ptr
}
// convenience version for integer-literal-creatable types
// that initializes to zero of that type
static func calloc<I: IntegerLiteralConvertible>
(num: Int) -> UnsafeMutablePointer<I> {
return UnsafeMutablePointer<I>.calloc(num, initialValue: 0)
}
}
// creates 100 UInt8s initialized to 0
var bits = UnsafeMutablePointer<UInt8>.calloc(100)
You could say:
bits.initializeFrom(Array<UInt8>(count: width * height, repeatedValue: 0))
I'm guessing there's some underlying efficiency to copying the memory this way. But of course there's an inefficiency in that we temporarily make the array. [NOTE: AirspeedVelocity's answer shows a way to avoid that.]
Personally, I liked your original loop best, especially if you write it more compactly, like this:
(0 ..< (width*height)).map {bits[$0] = 0}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With