【问题标题】:UnsafePointer<Int8> not workingUnsafePointer<Int8> 不工作
【发布时间】:2017-11-14 20:55:57
【问题描述】:

以下单元测试总是失败,因为某些 UnsafePointer 等于另一个。我观察到至少 3 个字符串的这种行为。 我在 High Sierra 版本 10.13.1 (17B48) 上使用 Xcode 版本 9.1 (9B55)。

func testUnsafePointer() {
    let a = "aaa"
    let b = "bbb"
    let c = "ccc"

    let ua = UnsafePointer<Int8>(a)
    let ub = UnsafePointer<Int8>(b)
    let uc = UnsafePointer<Int8>(c)

    print("a: '\(a)', ua: '\(ua)'")
    print("b: '\(b)', ub: '\(ub)'")
    print("c: '\(c)', uc: '\(uc)'")

    XCTAssertTrue(ua != ub)
    XCTAssertTrue(ub != uc)
    XCTAssertTrue(uc != ua)
}

打印输出与此类似

a: 'aaa', ua: '0x000060c000056a30'
b: 'bbb', ub: '0x00006080000530d0'
c: 'ccc', uc: '0x00006080000530d0'

注意。在 swift 的操场上,一切看起来都很好。

【问题讨论】:

  • UnsafePointer&lt;Int8&gt;(a) 几乎肯定不会像你认为的那样做——Swift 使用给定字符串的以 null 结尾的 UTF-8 字节创建一个新缓冲区,然后给你一个指向它的指针缓冲。调用结束后缓冲区被释放,所以你留下了一个悬空指针。因此,这些指针共享相同的值并不是不可能的。但是因为它们是悬空指针,所以试图取消引用它们是未定义的行为。无论您在此处尝试做什么,几乎肯定都不是正确的做法。
  • @Hamish 这解释了这种行为。我打算用这个签名将 swift 字符串传递给 C 函数:void cfunc(const char *a, const char *b, const char *c)。但是在这个 cfunc 中,只有第一个字符串很好,其他的都是垃圾。我用 UnsafePointer 转换调用这个 c 函数。
  • @swift616:您可以简单地调用cfunc(a, b, c),然后编译器会自动为转换创建必要的代码。

标签: swift unsafe-pointers


【解决方案1】:

let ua = UnsafePointer<Int8>(a)

init(_ other: UnsafePointer<Pointee>)

UnsafePointer 的初始化程序被调用。 IE。你正在路过 一个 Swift String 到一个采用 UnsafePointer&lt;Int8&gt; 的函数 争论。在这种情况下,创建一个 temporary C 字符串表示并将其传递给函数, 比较String value to UnsafePointer<UInt8> function parameter behavior

该临时 C 字符串仅在函数执行期间有效 调用,并在返回时,不能保证内存指向 to by ua 仍然包含该 C 字符串(或任何有效数据)。此外,

let ua = UnsafePointer<Int8>(a)
let ub = UnsafePointer<Int8>(b)
let uc = UnsafePointer<Int8>(c)

可以为临时 C 字符串使用相同的存储空间,在这种情况下 正如您所观察到的,指针将是相等的。


如果您的意图是调用带有 const char * 参数的 C 函数,那么您可以简单地传递 Swift 字符串。编译器 将插入必要的代码来创建 C 字符串表示 (在函数调用期间再次有效), 如String value to UnsafePointer<UInt8> function parameter behavior 中所述:

let a = "aaa"
let b = "bbb"
let c = "ccc"

cfunc(a, b, c)

【讨论】:

  • 就这么简单:) 谢谢
猜你喜欢
  • 2020-03-22
  • 2021-08-11
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 2017-02-20
相关资源
最近更新 更多