我使用 UnsafeMutablePointer 的 Swift 代码是否安全和/或产生未定义的行为?

问题描述

我有一个需要在我的 Swift 代码中使用的 C 库和一个需要 32 字节长的 UnsafeMutablePointer<UInt8>函数来从现有的私钥 (crypto_sign_public_key) 生成公钥。这是我正在调用的 C 函数文档的链接https://monocypher.org/manual/sign。我在 C 和指针方面没有太多经验,但我阅读了一些教程,并且有一些看起来很完美的东西。

除此之外,我想看看是否有比我更有经验的人能说出这段代码是否“安全”和/或是否会产生未定义的行为?

func generatePublicKey(from privateKey: [UInt8]) -> [UInt8] {
    /// Create an empty pointer that is 32 bytes long. The resulting public key will be written to the memory the pointer is pointing to.
    let publicKeyPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: 32)
        
    /// This is using the 25519 curve and the Blake2b hash method.
    /// Sign the private key and in turn,create the public key.
    crypto_sign_public_key(publicKeyPointer,privateKey)
        
    /// Go over the 32 bytes of the pointer and save it's locations as a "buffer"
    let buffer = UnsafeMutableBufferPointer(start: publicKeyPointer,count: 32)
        
    /// copy the data being pointed to,into an actual array.
    let publicKey = Array(buffer)
        
    /// Deallocate the memory being used by the pointer.
    publicKeyPointer.deallocate()
        
    return publicKey
}

谢谢!

解决方法

您的代码没问题,因为 UInt8 是一个普通类型,因此不需要您在分配的内存上调用 initializedeinitialize

但是,您可以完全避免手动分配和释放,如下所示:

func makePublicKey(withPrivateKey privateKey: [UInt8]) -> [UInt8] {
    var publicKey = [UInt8](repeating: 0,count: 32)
    publicKey.withUnsafeMutableBufferPointer { buffer in
        crypto_sign_public_key(buffer.baseAddress!,privateKey)
    }
    return publicKey
}