如果一个函数返回一个UnsafeMutablePointer,那么我们需要负责销毁和释放它吗?

18
例如,如果我写下这段代码:
var t = time_t()
time(&t)
let x = localtime(&t) // returns UnsafeMutablePointer<tm>
        
println("\(x.memory.tm_hour): \(x.memory.tm_min): \(x.memory.tm_sec)")

如果这样做,是否也需要做以下操作?

x.destroy()
x.dealloc(1)

或者我们没有分配内存,因此不需要释放它吗?


更新 #1:

如果我们想象一个返回 UnsafeMutablePointer 的函数:

func point() -> UnsafeMutablePointer<String> {
    let a = UnsafeMutablePointer<String>.alloc(1)
    a.initialize("Hello, world!")
    return a
}

调用此函数将导致指向一个对象的指针永远不会被销毁,除非我们自己进行清理工作。
我在这里提出的问题是:从localtime()调用中接收到的指针是否有所不同?模拟器和游乐场都能让我们向返回的指针发送一个dealloc(1)调用,但我们应该这样做吗?或者返回的指针的释放会在以后的某个时刻通过其他方法发生?目前我倾向于认为我们需要销毁和释放。
更新 #1.1: 上一个假设是错误的。我不需要释放,因为我没有创建对象。

更新 #2:

我在苹果开发者论坛上收到了一些答案,回应了相同的问题。

一般来说,如果您在C中接收了一个指向内存的指针,并负责释放它,那么当您从Swift调用时仍然需要负责释放它...但是在这种特殊情况下,您不需要做任何事情。(JQ)
这个例程本身为结果维护静态内存,您不需要释放它们。(如果您这样做可能会是一件“坏事”)...通常情况下,您无法知道是否需要释放由UnsafePointer指向的某些内容...这取决于该指针获取其值的位置。(ST)
UnsafePointer的dealloc()与free()不兼容。将alloc()与dealloc()配对,将malloc和co.与free()配对。正如先前指出的那样,您调用的函数应告诉您是否需要自己负责释放结果...只有在所指向的内存具有非平凡内容*时才需要destroy(),例如强引用或Swift结构或枚举。通常情况下,如果它来自C,则可能不需要destroy()。(实际上,您可能不应该destroy()它,因为它不是由Swift初始化的。)...... *“非平凡内容”不是官方的Swift术语。我使用它来类比于C ++的“可以平凡地复制”概念(虽然不一定是“平凡”的)。 (STE)

最终更新:

我已经撰写了一篇博客文章,概述了我的研究结果和假设,涉及不安全指针的发布,同时结合了StackOverflow、Apple Dev论坛、Twitter以及Apple在ARC之前分配内存和释放内存的旧文档的信息。请参见此处

1个回答

4

来自Swift库的UnsafeMutablePointer<T>

指向类型为T的对象的指针。这种类型不提供自动内存管理,因此用户必须注意适当地分配和释放内存

指针可以处于以下状态之一:

  • 未分配任何内存(例如,指针为空或先前已释放内存);
  • 已分配内存,但未初始化值;
  • 已分配内存并且已初始化值。

struct UnsafeMutablePointer<T> : RandomAccessIndexType, Hashable, NilLiteralConvertible { /**/}


在 Swift 语言中,你不需要为实例分配内存,但是从 Swift 开始,他们告诉你需要为 UnsafeMutablePointer 分配内存。@GoodbyeStackOverflow - Maxim Shoustin
我一直在研究UnsafeMutablePointers,并撰写了一篇关于分配和初始化、销毁和释放的博客文章。但是我提出这个问题的原因是因为我不确定当返回一个指针时会发生什么,而不是直接创建它。 - sketchyTech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接