Duck
Duck

Reputation: 35953

How do I convert an array of UnsafeMutablePointer<Double> to an array of Double?

I have created an array like this

var outputReal = UnsafeMutablePointer<Double>.allocate(capacity: numeroDados)

Now I need to convert that to an array of Double.

I can convert that using something like this:

var newArray : [Double] = []

for i in 0..<n {
  newArray[i] = outputReal
}

But I remember seeing on a page another method of doing this.

Any ideas?

Upvotes: 5

Views: 4335

Answers (3)

Vasily  Bodnarchuk
Vasily Bodnarchuk

Reputation: 25294

Details

  • Xcode 11.2.1 (11B500), Swift 5.1

Solution 1

extension UnsafeMutablePointer {
    func toArray(capacity: Int) -> [Pointee] {
        return Array(UnsafeBufferPointer(start: self, count: capacity))
    }
}

Usage of the solution 1

var array = [3.9, 7.7, 11.1, 1.11, 1.02, 3.3, 3.9, 0]
let pointer = UnsafeMutablePointer<Double>.allocate(capacity: array.count)
pointer.initialize(from: &array, count: array.count)
print(pointer.toArray(capacity: array.count))

Solution 2

extension Array {
    init(pointer: UnsafeMutablePointer<Element>, count: Int) {
        let bufferPointer = UnsafeBufferPointer<Element>(start: pointer, count: count)
        self = Array(bufferPointer)
    }
}

Usage of the solution 2

var array2 = [3.9, 7.7, 11.1, 1.11, 1.02, 3.3, 3.9, 0]
let pointer2 = UnsafeMutablePointer<Double>.allocate(capacity: array.count)
pointer2.initialize(from: &array, count: array.count)
print(Array(pointer: pointer2, count: array.count))

Upvotes: 7

Martin R
Martin R

Reputation: 539775

First create an UnsafeBufferPointer<Double> referencing the same memory area. That is a Collection so that you can create and initialize an array from that memory:

let bufPtr = UnsafeBufferPointer(start: outputReal, count: numeroDados)
let newArray = Array(bufPtr)

Alternatively, allocate an UnsafeMutableBufferPointer (which holds both the address and the size of the allocated memory) in the first place:

let numeroDados = 10

let outputReal = UnsafeMutableBufferPointer<Double>.allocate(capacity: numeroDados)
outputReal.initialize(repeating: 0.0)

let newArray = Array(outputReal)

In both cases the values are copied to the array's element storage, so you'll have to release the allocated memory eventually.

Upvotes: 8

Yuji
Yuji

Reputation: 74

Do you mean to convert the Pointer to double to an Array of double??

You shouldn't cast a pointer to double to array of double in swift since array in swift is not necessarily the same as a C array. Instead, you copy the contents into the new array. A "low-level" way to do it is

var pointerToDoubles = UnsafeMutablePointer<Double>.allocate(capacity: 10)
var newArray = Array<Double>(repeating: 0, count: 10)
_ = newArray.withContiguousMutableStorageIfAvailable {
  UnsafeMutableRawPointer($0.baseAddress!).copyMemory(from: x, byteCount: MemoryLayout<double>.size * 10)
}

Please keep in mind this is not safe and will crash if you made some mistakes, for example your new array is too small or if your pointer don't not have as many elements you expecting.

Upvotes: 1

Related Questions