【问题标题】:Assigning a manually allocated UnsafeMutablePointer<String>分配手动分配的 UnsafeMutablePointer<String>
【发布时间】:2019-12-15 23:14:16
【问题描述】:

我想将指针的指针值分配给手动分配的字符串。 换句话说,我想写这样的东西:

let pointer = UnsafeMutablePointer<String>.allocate(1)
pointer.pointee = "Hello, World!"

// ...

pointer.deallocate()

不幸的是,这段代码有时会在第二行(即赋值)崩溃。

如果指针的类型是数组,则可以观察到相同的行为。 但是,如果指针的类型不包含动态分配的存储(例如简单的Int),该程序似乎永远不会失败。 这表明只有当指针的类型包装指向堆的指针时才会出现问题,例如StringArray

有没有办法解决这个问题?

我试图实现这一目标的原因是创建一个通用的内存领域。

【问题讨论】:

    标签: swift memory-management unsafe-pointers


    【解决方案1】:

    来自official documentation

    刚刚通过类型化指针分配或已取消初始化的内存处于未初始化状态。 未初始化的内存必须先初始化后才能被读取。

    这解释了为什么代码不起作用。 指针的内存已分配,但尚未初始化。 虽然这与简单的值类型(例如Int)无关,但不适用于更复杂的类型,如StringArray。 这些可能包含指向 Swift 运行时在后台管理的堆内存的指针。 因此,如果没有适当的初始化,运行时可能会在尝试对这些隐藏指针执行操作时崩溃。

    在这个特定示例中,问题在于运行时在分配新值之前尝试释放先前分配给指针对象的内存(即包含字符串字符的底层堆存储),但由于从未分配过此内存而崩溃.

    程序应修正如下:

    let pointer = UnsafeMutablePointer<String>.allocate(1)
    pointer.initialize(to: "Hello, World!")
    
    // ...
    
    pointer.deallocate()
    

    【讨论】:

    • 如果你想要一个通用的缓冲区,那就是 Data 。你在这里做的事情看起来违反了一般的 Swift 内存原则,并且可能会走向崩溃。
    • 我知道这种方法不是 Swifty。目标是创建一个高效的内存领域,工厂将使用它来保证它创建的对象的唯一性。我可以使用类,但我想尽可能避免内存分配。
    • 当我使用 Int 类型的指针时的事件,例如UnsafeMutablePointer&lt;Int&gt;.allocate(1),它可能仍然会崩溃。经过几十次试验后,我遇到了崩溃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 2015-07-31
    相关资源
    最近更新 更多