Bobj-C Bobj-C - 1 year ago 48
Swift Question

How to get an UnsafeMutableBufferPointer<Character> from array of Character

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


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 buffer is allocated, but the closure is called with a pointer to the arrays contiguous storage. This buffer pointer is only valid inside the closure.