指针去初始化后我可以使用内存吗?



指针去初始化后我可以使用内存吗?

let q = UnsafeMutablePointer<Float>.allocate(capacity: 1)
q.pointee = 123.125
let bq = UnsafeRawBufferPointer(start: q.deinitialize(count: 1), count: 4) // (*)
for i in bq.reversed() {
print(String(i, radix: 16), terminator: " ")
}
q.deallocate()
print()

这是我这个任务的核心解决方案:https://pl.spoj.com/problems/PP0504D/

任务中的问题很简单:写一个函数来表示浮点值的机器字节。

float2bytes(123.125) prints 42 f6 40 0但这不是问题的关键。

我没有深入研究指针。我的疑问是:我可以使用内存去初始化后,这是由另一个指针点(这个内存不释放)?反初始化的真正含义是什么?

let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
p.initialize(to: 7)
print(p.pointee)
p.initialize(to: 9)
p.deinitialize(count: 1)
// something may crash the memory in this place?
print(p.pointee)
p.deallocate()

谁能告诉我在deinicialize(count:)之后导致崩溃的代码?

指针不初始化。内存。当您调用q.deinitialize(count: 1)时,您已经初始化了q所指向的内存。然后读取未初始化内存是无效的。它几乎肯定会"奏效"。因为这是一个普通的类型(浮点数),但它是无效的。

内存有比"已分配"更多的状态。和"收回!"它还需要被绑定和初始化。当调用deinitialize时,内存被放回未初始化状态(但仍然绑定),但在读取之前必须重新初始化。

完整的细节,参见WWDC 2020中的Swift安全管理指针。

对于你所描述的特定情况,你不需要内存管理。您可以直接向系统询问值的字节数:

let value: Float = 123.125
withUnsafeBytes(of: value) { q in
for i in q.reversed() {
print(String(i, radix: 16), terminator: " ")
}
}
我知道你可能还有别的问题要解决。但这就是你所描述的。) 对于第二个示例,您可能永远不会看到崩溃(因为Float是微不足道的)。但它的行为是不确定的。一旦调用了未定义的行为,您可能会对编译器允许应用的优化感到非常惊讶。例如,这可以不打印任何内容,或者打印一些常量值。或者它可能会崩溃(可能不会,但有可能)。或者它可以完美地工作,但仍然是错误的。

虽然@RobNapier的答案肯定是正确的,但您也可以使用bitPattern属性访问Float的"原始位":

let f: Float = 123.125
let bits = f.bitPattern

然后你可以把比特分割成字节:

let bytesLittleEndian = stride(from: 0, to: UInt32.bitWidth, by: 8)
.map { UInt8(truncatingIfNeeded: bits >> $0) }
let bytesBigEndian = stride(from: 0, to: UInt32.bitWidth, by: 8)
.reversed()
.map { UInt8(truncatingIfNeeded: bits >> $0) }

感谢Rob Napier的解释。当我还不知道指针的时候,我这样解决了这个问题:

import Foundation
let k = Int(readLine()!)!
for _ in 1...k {
let n = String(Float(readLine()!
.trimmingCharacters(in: .whitespaces))!
.bitPattern, radix: 16)
let f = ((n + repeatElement("0", count: 8 - n.count))
.reduce("") {
"($0)" + "(($0.count + 1) % 3 == 0 ? "'" : "")" + "($1)"
} as String)
.split(separator: "'")
.map {
$0 == "00" ? "0" : $0
}
.reduce("") {
"($0)($1) "
}
print(f)
}

但是现在我想知道如何为代码编写UI测试

//file
import Foundation
let k = Float(readLine()!)!
print(k)

相关内容

最新更新