I am trying to get an UnsafeMutableBufferPointer using the following code it works sometimes in Playground and it fails also
let array : [Character] = ....
func getUnsafeMP(array: [Character]) -> UnsafeMutableBufferPointer<Character> {
let count = array.count
let memory = UnsafeMutablePointer<Character>(allocatingCapacity: count)
for (index , value) in array.enumerated() {
memory[index] = value //it fails here EXC_BAD_ACCESS
}
let buffer = UnsafeMutableBufferPointer(start: memory, count: count)
return buffer
}
Memory addressed by UnsafeMutablePointer
can be in one of
three states:
/// - Memory is not allocated (for example, pointer is null, or memory has
/// been deallocated previously).
///
/// - Memory is allocated, but value has not been initialized.
///
/// - Memory is allocated and value is initialised.
The call
let memory = UnsafeMutablePointer<Character>(allocatingCapacity: count)
allocates memory, but does not initialize it:
/// Allocate and point at uninitialized aligned memory for `count`
/// instances of `Pointee`.
///
/// - Postcondition: The pointee is allocated, but not initialized.
public init(allocatingCapacity count: Int)
On the other hand, the subscripting methods require that the pointee is initialized:
/// Access the pointee at `self + i`.
///
/// - Precondition: the pointee at `self + i` is initialized.
public subscript(i: Int) -> Pointee { get nonmutating set }
As a consequence, your code crashes inside _swift_release_
.
To initialize the allocated memory from the (character) array, you can use
memory.initializeFrom(array)
Of course you must de-initialize and deallocate the memory eventually.
A different approach is
var cArray: [Character] = ["A", "B", "C"]
cArray.withUnsafeMutableBufferPointer { bufPtr in
// ...
}
Here no new memory is allocated, but the closure is called with a pointer to the arrays contiguous storage. This buffer pointer is only valid inside the closure.