Crash assigning Float[] to CMutablePointer<Float> in Swift - swift

If I assign a float array to a CMutablePointer<Float> in a Swift playground as follows, I get a runtime crash:
var floatArray:Float[] = Array(count: 3, repeatedValue: 2.5)
var floatPointer:CMutablePointer<Float> = &floatArray
Is my code incorrect (if so how?), or should I file this as a bug with Apple?

Your param is a tab so you have to do like this
var floatArray:Float[] = Array(count: 3, repeatedValue: 2.5)
var floatPointer:CMutablePointer<Float[]> = &floatArray

Your code, when compiled and run outside of the Playground:
var floatArray:Float[] = Array(count: 3, repeatedValue: 2.5)
var floatPointer:CMutablePointer<Float> = &floatArray
floatPointer.withUnsafePointer { (myPtr1 : UnsafePointer<Float>) -> () in
var x = myPtr1.memory
println("float array element 0 is \(x)")
}
prints 2.5

Related

Extracting the real part of an UnsafeMutablePointer as a Float and storing that on an array

I have this function
func arrayForPointer<T>(_ pointer: UnsafePointer<T>, count: Int) -> [T] {
let buffer = UnsafeBufferPointer<T>(start: pointer, count: count)
return Array(buffer)
}
and this call
let arrayComplex = self.arrayForPointer(&output, count: 4)
I want to enumerate thru arrayComplex and extract the real part to a regular array, like
var arrayReal: [Float] = []
for item in arrayComplex {
let myFloat = item.realp \\ get the real part of item
arrayReal.append(myFloat)
}
line
let myFloat = item.realp \\ get the real part of item
is not correct.
item is a UnsafeMutablePointer<Float>
How do I do that, for heavens sake?
Thanks.
=======================
This is output
var A = [Float](repeating:0, count:samples/2);
var B = [Float](repeating:0, count:samples/2)
var output = DSPSplitComplex(realp: &A, imagp: &B)
Try this.
Fix your func call:
let arrayComplex = arrayForPointer(output.realp, count: 4)
And then in your loop fix this line:
let myFloat = item \\ get the real part of item

Pointer and malloc in Swift

I am trying to convert this into swift.
Facing issue at memory allocation logic
Byte *p[10000];
p[allocatedMB] = malloc(1048576);
memset(p[allocatedMB], 0, 1048576);
How to write this in swift?
You can use malloc from Swift, it returns a "raw pointer":
var p: [UnsafeMutableRawPointer?] = Array(repeating: nil, count: 10000)
var allocatedMB = 0
p[allocatedMB] = malloc(1048576)
memset(p[allocatedMB], 0, 1048576)
Alternatively, use UnsafeMutablePointer and its
allocate and initialize methods:
var p: [UnsafeMutablePointer<UInt8>?] = Array(repeating: nil, count: 10000)
var allocatedMB = 0
p[allocatedMB] = UnsafeMutablePointer.allocate(capacity: 1048576)
p[allocatedMB]?.initialize(to: 0, count: 1048576)

Is there a way to override the Copy on Write behavior for Swift arrays?

I'm working on a project where I need to work with large arrays, and by using UnsafeMutablePointers, I get a threefold speed increase over using the regular array methods. However, I believe the copy on write behavior is causing me to change instances that I do not want to be affected. For example, in the following code, I want to update the values in copyArray, but leave the original values in anArray.
import Foundation
func increaseWithPointers(_ arr: inout [Int]) {
let count = arr.count
let ptr = UnsafeMutablePointer(mutating: &arr)
for i in 0..<count {
ptr[i] = ptr[i] + 1
}
}
var anArray = [1,2,3,4,5]
var copyArray = anArray
increaseWithPointers(&copyArray)
print(anArray)
Executing this code prints [2,3,4,5,6].
I can get around this by declaring copyArray as follows:
var copyArray = [Int](repeating: 0, count: 5)
for i in 0..<5 {
copyArray[i] = anArray[i]
}
However, this requires writing each value twice: to zero, then to the intended value. Is there a way to efficiently guarantee a copy of an array?
I can reproduce your problem using Xcode 9 beta 3, but not using Xcode 8.3.3. I suggest you file a Swift bug report.
This fixes the problem:
import Foundation
func increaseWithPointers(_ arr: inout [Int]) {
arr.withUnsafeMutableBufferPointer { (buffer) in
for i in buffer.indices {
buffer[i] += 1
}
}
}
var anArray = [1,2,3,4,5]
var copyArray = anArray
increaseWithPointers(&copyArray)
print(anArray)

How to use an array to store scores per round

I want to create a new array programmatically every round to store that rounds scores. So say I have
var roundNumber = 3
var team1Score = 5
var team2Score = 7
And I would store these in array
var scores = [Int]()
scores.append(team1Score)
scores.append(team2Score)
print (scores)
How would I dynamically change the name and then store the scores from that round so that I can load them at a later time. Or store that array into another array and create a new one so I can call upon it later and fill the new array with the current rounds scores without typing out every new array?
I prefer to use array of structs, something like below
struct Result {
let round: Int
let team1Score: Int
let team2Score: Int
}
var results = [Result]()
// round 1
let result = Result(round: 1, team1Score: 7, team2Score: 5)
results.append(result)
// round N or maybe could be done in loop
let resultN = Result(round: 2, team1Score: 17, team2Score: 10)
results.append(resultN)
class ScoreCard{
var round:Int?
var player1Score:Int?
var player2Score:Int?
}
var s = [ScoreCard]()
let scoreCard = ScoreCard()
scoreCard.round = 1
scoreCard.player1Score = 10
scoreCard.player2Score = 20
s.append(scoreCard)
This will do the job I guess.
You can use a dictionary and tuples for what you seem to be after.
Store the score of each round in a tuple:
var round1 = (team1score: 1, team2score: 3)
Then create a dictionary (dict) to store the tuple with the name you associated with it:
var scores: [String: (team1score: Int, team2score: Int)] = [:]
scores["1"] = round1
var anotherRound = (team1score: 12, team2score: 32)
scores["some round"] = anotherRound
print (scores)
You can define the dictionary to use the number of the round as the key, if that is what you need. Then the code would look like:
var round1 = (team1score: 1, team2score: 3)
var scores: [Int: (team1score: Int, team2score: Int)] = [:]
scores[1] = round1
var anotherRound = (team1score: 12, team2score: 32)
scores[4] = anotherRound
print (scores)
For doing stuff with the scores data, you can iterate easily:
for (round, score) in scores {
print("round \(round) had winner score \(max(score.team1score,score.team2score))")
}

Binary operator '+' cannot be applied to two 'NSNumber' operands -- swift 3

Help. I just converted to swift 3 and am getting errors when I try to add two NSNumbers together i.e.:
var foodPrice: NSNumber!
var priceSum: NSNumber!
foodPrice = 6.79
priceSum = 11.89
var totalSum = NSNumber(foodPrice + priceSum) // <-- error here
OR
var totalSum = (foodPrice + priceSum) as NSNumber // <-- still error here
Doesn't matter how I change totalSum I can't get away from this error. Please help. This is my official SOS. Dazed and confused here. How do I make this work?
Why not write your own + override for NSNumber?
func + (lhs: NSNumber, rhs: NSNumber) -> NSNumber {
return NSNumber(value: lhs.floatValue + rhs.floatValue)
}
var foodPrice: NSNumber = 6.79
var priceSum: NSNumber = 11.89
var totalSum = foodPrice + priceSum // 18.68
I use floats here but you can use any type you need.
var foodPrice: NSNumber!
var priceSum: NSNumber!
foodPrice = 6.79
priceSum = 11.89
var totalSum = NSNumber(double: foodPrice.doubleValue + priceSum.doubleValue)
Try this out..!
Try
var totalSum = NSNumber(value: foodPrice.doubleValue + priceSum.doubleValue)