gpt4 book ai didi

ios - 初始化 'UnsafePointer' 导致指针悬空

转载 作者:行者123 更新时间:2023-12-01 18:35:01 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





UnsafeMutablePointer Warning with Swift 5

(3 个回答)



Warning: Initialization of 'UnsafeBufferPointer<T>' results in a dangling buffer pointer

(6 个回答)



Initialization of 'UnsafeMutableRawPointer' results in a dangling pointer

(1 个回答)


2年前关闭。




所以我有一些代码来创建 H264ParameterSets,例如:

var formatDesc: CMVideoFormatDescription?

func createH264FormatDescription(SPS: Array<UInt8>, PPS: Array<UInt8>) -> OSStatus {
if formatDesc != nil { formatDesc = nil }

let paramSet = [UnsafePointer<UInt8>(SPS), UnsafePointer<UInt8>(PPS)]
let paramPointers = UnsafePointer<UnsafePointer<UInt8>>(paramSet)
let paramSizes = UnsafePointer<Int>([SPS.count, PPS.count])

let status = CMVideoFormatDescriptionCreateFromH264ParameterSets(allocator: kCFAllocatorDefault, parameterSetCount: 2, parameterSetPointers: paramPointers, parameterSetSizes: paramSizes, nalUnitHeaderLength: 4, formatDescriptionOut: &formatDesc)

return status
}

从 Xcode 11.4 开始,我收到了有关 UnsafePointer() 的警告,这似乎以前没有发生过:
Initialization of UnsafePointer<UInt8> results in a dangling pointer

Initialization of UnsafePointer<UnsafePointer<UInt8>> results in a dangling pointer

Initialization of UnsafePointer<Int> results in a dangling pointer

我不知道为什么我们会看到这个?以及如何删除警告?预先感谢。

最佳答案

解释此警告的最简单方法是查看导致该警告的一种情况。那么让我们从使用 SPS 开始吧。 .

这是一个 Array<UInt8>所以它由 UInt8 的缓冲区支持就像在 C 中一样。当你通过 SPS 时与 UnsafePointer<UInt8>(SPS)它为那一刻创建一个指向缓冲区的有效指针。问题是你可以改变 SPS通过向其附加另一个值来说。这意味着支持 Array 的缓冲区可能会移动到内存中的另一个位置。这意味着您的指针现在是 paramSet 的一部分是无效的。

另一个问题是,如果你将这个指针传递给某个东西,就像你在这种情况下所做的那样,另一个函数可能会尝试保持它,然后它有一个无效的指针。因此,如果您希望其他函数保留指针,您需要使用 UnsafePointer 手动管理内存s 和 Unmanaged你自己。如果 CMVideoFormatDescriptionCreateFromH264ParameterSets()不保留指针,那么我将分享的代码是正确的,如果确实如此,您将需要对其进行调整以根据需要创建/销毁内存。

另外值得注意的是,在这种情况下,您不能改变任何 Array s 你有,因为它们是常数,但总的来说,原则仍然是相同的。这意味着理论上它永远不会被改变,但 Swift 编译器更愿意帮助我们编写尽可能安全和正确的代码,即使是 UnsafePointer类型。

那么你怎么能解决这个问题呢?您需要能够调用 withUnsafeBufferPointer然后通过UnsafeBufferPointer访问指针像这样:

var formatDesc: CMVideoFormatDescription?

func createH264FormatDescription(SPS: Array<UInt8>, PPS: Array<UInt8>) -> OSStatus {
if formatDesc != nil { formatDesc = nil }

let status = SPS.withUnsafeBufferPointer { SPS in
PPS.withUnsafeBufferPointer { PPS in
let paramSet = [SPS.baseAddress!, PPS.baseAddress!]
let paramSizes = [SPS.count, PPS.count]
return paramSet.withUnsafeBufferPointer { paramSet in
paramSizes.withUnsafeBufferPointer { paramSizes in
CMVideoFormatDescriptionCreateFromH264ParameterSets(allocator: kCFAllocatorDefault, parameterSetCount: 2, parameterSetPointers: paramSet.baseAddress!, parameterSetSizes: paramSizes.baseAddress!, nalUnitHeaderLength: 4, formatDescriptionOut: &formatDesc)
}
}
}
}
return status
}

这种方法有效的原因是对于 withUnsafeBufferPointer 的范围排他性法则正在保护阵列,因此它们不能被变异。

如果您担心 baseAddress!用法你可以检查它不是 nil但保证不是 nilcount > 0根据编译器工程师的说法(他们已经在 Twitter 或我忘记的 Swift 论坛上说明了这一点......)。

关于ios - 初始化 'UnsafePointer<Int>' 导致指针悬空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61263174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com