memset with Swift 5.2 - swift

Sometimes I need to clear a part of a byte array to zero. With a for loop this is slow. Much faster is using the memset() function. I have the following code which will clear elements 200 to 299 of the array "a".
var a: [UInt8] = [UInt8](repeating: 1, count: 1000) // a[0..999] set to 1
start = 200
length = 100
memset(&a + start, 0, length) // a[100..199] set to 0
This worked well until Swift 5.2 with Xcode 11.4 came out. Now it works, too, but a warning appears:
Inout expression creates a temporary pointer, but argument #1 should be a pointer that outlives the call to '+'
How can this made, to have no warning.? Andybody has an idea?
Some more explanations is whows in Xcode:
Implicit argument conversion from '[UInt8]' to 'UnsafeMutableRawPointer' produces a pointer valid only for the duration of the call to '+'
Use the 'withUnsafeMutableBytes' method on Array in order to explicitly convert argument to buffer pointer valid for a defined scope
I do not understand, what this means.

The hint to use withUnsafeMutableBytes is exactly what you should follow:
a.withUnsafeMutableBytes { ptr in
_ = memset(ptr.baseAddress! + start, 0, length)
}

Related

Array cannot be inferred Error in Xcode 12 with Swift 5

Here is the simple code:
var buffer = [UInt8](_data)
var sec_ivs = [UInt8](repeating: 0, count: 8);
memcpy(&sec_ivs + 3, &buffer, 5);
The Xcode stop building the project with the following error:
How can I rewrite this code to make it works again in Xcode 12? This code is working fine in Xcode 11, but Xcode 11 did not support iOS 14 debuging.Thanks for help.
You can pass the address of the (mutable) element storage of an array to a C function with
memcpy(&sec_ivs, buffer, 5)
but that does not work with offsets. Here you need to use withUnsafeMutableBytes() to obtain a buffer pointer, so that you can add an offset:
sec_ivs.withUnsafeMutableBytes {
memcpy($0.baseAddress! + 3, buffer, 5);
}
Note that the & operator is not needed for the second argument of memcpy() because that is a constant pointer argument.
A simpler solution would an assignment to a slice of the target array:
sec_ivs[3..<8] = buffer[0..<5]

Binary operator '+' cannot be applied to operands of type 'Int' and '[Int]'

I'm trying to write code that will update my array and give total pay based on the daily pay. I'm getting an error about binary operators so how do I fix this line code so that doesn't happen.
for day in stride(from: 1, to: 31, by: 1)
{
dailyPay[day] = [Int(pay)]
pay*=2
if(day==1)
{
totalPay[day] = Int(pay)
}
else
{
totalPay[day] = totalPay[day-1]+dailyPay[day]//The problem is Here
print("\(heade) \(day) \(head) \(dailyPay[day]) \(total) \(totalPay[day])")
}
You don't show the declarations of your variables, but it appears that totalPay is an array of Ints, whereas dailyPay is a two-dimensional array of arrays of Int. So, totalPay[day-1] will be an Int, whereas dailyPay[day] will be an [Int], or an array of Ints. The error you're getting therefore means exactly what it says; you can't use + to add an Int and an array.
From your code, it appears that dailyPay is probably meant to be a plain old array of integers, like totalPay. So you could fix this by changing the declaration, whereever it is, from:
var dailyPay: [[Int]]
to:
var dailyPay: [Int]
Then, change the assignment to:
dailyPay[day] = Int(pay)
and things should work.
Sidenote: Your for loop is needlessly complex. There's no need for stride, when you can just:
for day in 1...31

'initializeMemory(as:at:count:to:)' is deprecated

As is, I'm using the following code to set a value at an index of a UnsafeMutableRawPointer (the pointer points to an array):
ptr.initializeMemory(as: Float.self, at: idx, count: 1, to: someValue)
This works and sets ptr at idx to someValue. But Xcode is giving me a warning saying that said method is deprecated, and suggesting me to use initializeMemory(as:repeating:count:) instead. However, such method doesn't have an index parameter.
So, my question is: which function should I use in order to appropriately set the value of an UnstableMutableRawPointer at some index?

Fatal Error: Array Index out of range in Swift Xcode6

I keep getting this error in my func
I'm trying to read the value in array answerRecord. I uses a global var arrayCount, which keep track which index im currently pointing to.
func buttonColourControl(){
switch answerRecord[arrayCount]{
case1: xxxxxxx
I did a println in my earlier func and it return a value of int 1 for the var arrayCount
Therefore arrayCount is not empty. So it should be able to interpret the array as:
*assuming arrayCount is now 1
answerRecord[arrayCount] should be interpreted as answerRecord[1]
Please correct me if im wrong
#IBAction func nextButtonClicked(sender: UIButton) {
arrayCount = ++arrayCount
question.text = spouseQuesion[arrayCount]
controlBackNextButton()
answer1Label.text = spouseAnswer1[arrayCount]
answer2Label.text = spouseAnswer2[arrayCount]
answer3Label.text = spouseAnswer3[arrayCount]
println(arrayCount)
buttonColourControl()
}
Let's say you have an array with one object in it:
let arr = ["hello"]
The only valid index into that array is 0. arr[0] is legal. arr[1] is not. The array has 1 element but its index number is 0.
This is true for any array. Every array holds some number of elements. It might be 0 elements, in which case no index is legal. It might be 3 elements, in which case you can refer to the array's elements by index numbers 0, 1, and 2. And so on. That's all. Those are the rules. You cannot use any other index number or you will crash.
So the error message is simply telling you that you are making that mistake. You have an array answerRecord and it has some number of elements - I have no idea how many, and it doesn't matter. Then you are using the expression answerRecord[arrayCount] and the value of arrayCount is outside the bounds I have just explained. That's all you need to know. The error message tells you the bug in your program. Now you can fix it.

float arrays in objective C

Do I need to null-terminate a basic float array in objective C?
I have a basic float array:
float data[] = {0.5, 0.1, 1};
and when I do a sizeof(data) I get "12".
You don't need to null terminate it to create one, no. And in general a method taking a float[] would also take a size parameter to indicate how many elements there are.
You get sizeof(data) = 12 because a float is 4-bytes on your architecture and there's 3 of them.
sizeof return the amount of memory (in bytes) occupied by the parameter. In your case, every float occupies 4 bytes, thus 4*3=12.
As Hot Licks said in the comment of mattjgalloway's answer, there is not a standard way to retrieve the number of elements in a C array.
Using size = sizeof(data) / sizeof(float) works, but you must be careful in using this approach, since if you pass the array as a parameter it won't work.
A common approach is to store the size in a variable and use it as upper bound in your for loop (often functions that expect an array have an additional parameter to get the size of the array).
Using a null-terminated array is useful because you can iterate through your array and stop when the i-esim element is null (that's the approach of methods like strcmp).
Values of type float can never be null, so it's not possible to terminate an array of type float with null. For one thing, variables of any primitive type always have a numeric value, and the various null constants (in Objective-C nil, Nil, NULL, and '\0') have the literal value 0, which is obviously a valid value in range of a float.
So even if you can compile the following line without a warning,
float x = NULL;
...it would have the same consequence as this:
float x = 0;
Inserting a null constant in an array of type float would be indistinguishable from inserting 0.0 or any other constant zero value.