gpt4 book ai didi

swift - 'UnsafeMutableRawPointer' 的初始化导致悬空指针

转载 作者:行者123 更新时间:2023-12-02 03:46:36 26 4
gpt4 key购买 nike

自 Xcode 11.4 起,我收到警告消息“‘UnsafeMutableRawPointer’的初始化导致悬空指针”

对于以下代码,我将 SIMD4 从 MTLTexture 读取到数组中:

let texArray = Array<SIMD4<Float>>(repeating: SIMD4<Float>(repeating: 0), count: 1)

texture.getBytes(UnsafeMutableRawPointer(mutating: texArray), bytesPerRow: (MemoryLayout<SIMD4<Float>>.size * texture.width), from: region, mipmapLevel: 0)

有人能弄清楚如何创建数组指针来消除警告吗?

谢谢

最佳答案

TLDR

使文本数组可变(使用var而不是let)并使用withUnsafeMutableBytes

var texArray = Array<SIMD4<Float>>(repeating: SIMD4<Float>(repeating: 0), count: 1)
texArray.withUnsafeMutableBytes { texArrayPtr in
texture.getBytes(texArrayPtr.baseAddress!, bytesPerRow: (MemoryLayout<SIMD4<Float>>.size * texture.width), from: region, mipmapLevel: 0)
}

说明

引入该警告是因为编译器无法确保支持指针的数据不会被释放。假设您有一个函数(例如用 C 实现)来操作某些指向的数据。

func f(_ a: UnsafeMutablePointer<Int>){
a[0] = 42
}

然后必须确保在调用结束之前内存不会被释放。所以当用下面的方式调用这个函数时是不安全的

var a: = [1]
p: UnsafeMutablePointer<Int>(&a)
// at this point the compiler may optimise and deallocate 'a' since it is not used anymore
f(p)

据我所知,目前这不会成为问题,因为局部变量在作用域结束之前不会被释放。可以通过以下方式引入嵌套范围来说明可能的问题

var p: UnsafeMutablePointer<Int>?
do {
var a = [1]
p = UnsafeMutablePointer<Int>(&a)
} // "a" will be deallocated here
// now "p" is a dangling pointer the compiler warned you of
var b = [0] // compiler will use same memory as for "a", so manipulating memory of "p" won't segfault
f(p!) // manipulate memory
print(b[0]) // prints 42 although "b" was initialised to 0

由于 b 分配的内存与 a 之前使用的内存相同,因此 b 的内存会通过调用来修改f(p!)。因此,b[0] 是 42,尽管它已初始化为 0 并且未显式修改。

通过这个例子,我们应该清楚为什么 Swift 数组上有方法 withUnsafeMutableByteswithUnsafeMutableBufferPointer 以及全局函数 withUnsafeMutablePointer 以及不可变变体。 (我个人觉得令人困惑的是,方法必须在数组上使用,全局函数必须在结构上使用。)这些函数确保在闭包范围内不会释放(或重用)内存(我还通过一些示例创建了 gist)。

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

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