1

次のコードを使用して UnsafeMutableBufferPointer を取得しようとしていますが、Playground で時々動作し、失敗することもあります

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
}
4

2 に答える 2

7

によってアドレス指定されるメモリは、UnsafeMutablePointer次の 3 つの状態のいずれかになります。

/// - 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.

呼び出し

let memory = UnsafeMutablePointer<Character>(allocatingCapacity: count)

メモリを割り当てますが、初期化はしません:

/// 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)

一方、添え字メソッドでは、指示先が初期化されている必要があります。

/// Access the pointee at `self + i`.
///
/// - Precondition: the pointee at `self + i` is initialized.
public subscript(i: Int) -> Pointee { get nonmutating set }

その結果、コードが 内でクラッシュします_swift_release_

(文字)配列から割り当てられたメモリを初期化するには、次を使用できます

memory.initializeFrom(array)

もちろん、最終的にはメモリを初期化解除して割り当てを解除する必要があります。


別のアプローチは、

var cArray: [Character] = ["A", "B", "C"]
cArray.withUnsafeMutableBufferPointer { bufPtr  in
    // ...
}

ここでは、新しいメモリは割り当てられませんが、配列の連続したストレージへのポインターを使用してクロージャーが呼び出されます。このバッファ ポインタは、クロージャ内でのみ有効です。

于 2016-07-10T15:48:34.110 に答える