如果一个函数返回一个UnsafeMutablePointer,我们的责任是销毁和dealloc吗?

时间:2021-12-14 20:05:52

For example if I were to write this code:

例如,如果我要写这个代码:

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)")

...would it also be necessary to also do the following?

…是否也需要做以下的事情?

x.destroy()
x.dealloc(1)

Or did we not allocate the memory and so therefore don't need to dismiss it?

或者我们没有分配内存所以不需要对它进行解压?


Update #1:

If we imagine a function that returns an UnsafeMutablePointer:

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

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

Calling this function would result in a pointer to an object that will never be destroyed unless we do the dirty work ourselves.

调用这个函数会导致指向一个对象的指针,除非我们自己做这些脏工作,否则它不会被销毁。

The question I'm asking here: Is a pointer received from a localtime() call any different?
The simulator and the playground both enable us to send one dealloc(1) call to the returned pointer, but should we be doing this or is the deallocation going to happen for a returned pointer by some other method at a later point?

我在这里提出的问题是:从localtime()调用接收的指针有什么不同吗?模拟器和游乐场都允许我们向返回的指针发送一个dealloc(1)调用,但是我们应该这样做,还是应该在以后用其他方法对返回的指针进行释放?

At the moment I'm erring towards the assumption that we do need to destroy and dealloc.

现在我犯了一个错误,认为我们确实需要毁灭和交易。

Update #1.1:

The last assumption was wrong. I don't need to release, because I didn't create object.

最后一个假设是错误的。我不需要释放,因为我没有创建对象。


Update #2:

I received some answers to the same query on the Apple dev forums.

我在苹果开发论坛上收到了一些相同的答案。

In general, the answer to your question is yes. If you receive a pointer to memory which you would be responsible for freeing in C, then you are still responsible for freeing it when calling from swift ... [But] in this particular case you need do nothing. (JQ)

总的来说,你的问题的答案是肯定的。如果您收到一个指向内存的指针,您将负责在C语言中释放它,那么当从swift调用时,您仍将负责释放它……但是在这种情况下你什么都不需要做。(金桥)

the routine itself maintains static memory for the result and you do not need to free them. (it would probably be a "bad thing" if you did) ... In general, you cannot know if you need to free up something pointed to by an UnsafePointer.... it depends on where that pointer obtains its value. (ST)

例程本身为结果维护静态内存,您不需要释放它们。(如果你这么做,那可能是件“坏事”)……一般来说,你无法知道你需要释放一些指出由UnsafePointer ....它取决于指针在哪里获得它的值。(圣)

UnsafePointer's dealloc() is not compatible with free(). Pair alloc() with dealloc() and malloc and co. with free(). As pointed out previously, the function you're calling should tell you whether it's your response to free the result ... destroy() is only necessary if you have non-trivial content* in the memory referred to by the pointer, such as a strong reference or a Swift struct or enum. In general, if it came from C, you probably don't need to destroy() it. (In fact, you probably shouldn't destroy() it, because it wasn't initialized by Swift.) ... * "non-trivial content" is not an official Swift term. I'm using it by analogy with the C++ notion of "trivially copyable" (though not necessarily "trivial"). (STE)

UnsafePointer的dealloc()与free()不兼容。将alloc()与dealloc()和malloc及co.进行*()配对。正如前面所指出的,您正在调用的函数应该告诉您,这是否是您释放结果的响应……只有在指针引用的内存中有非平凡的内容*时才需要destroy(),比如强引用、快速结构或枚举。一般来说,如果它来自C,那么您可能不需要销毁它。(实际上,您可能不应该销毁()它,因为它不是由Swift初始化的。)*“非琐碎内容”不是一个正式的快速词汇。我用它来类比c++的“trivially copyable”(虽然不一定是“琐碎的”)的概念。(STE)


Final Update:

I've now written a blogpost outlining my findings and assumptions with regard to the release of unsafe pointers taking onboard info from *, Apple Dev Forums, Twitter and Apple's old documentation on allocating memory and releasing it, pre-ARC. See here.

我现在写了一篇博文,概述了我在发布不安全指针方面的发现和假设,这些指针从*、苹果开发论坛、Twitter和苹果关于内存分配和释放的旧文档中获取信息。在这里看到的。

1 个解决方案

#1


4  

From Swift library UnsafeMutablePointer<T>

从斯威夫特图书馆UnsafeMutablePointer < T >

A pointer to an object of type T. This type provides no automated memory management, and therefore the user must take care to allocate and free memory appropriately.

指向t类型对象的指针不提供自动内存管理,因此用户必须小心分配和释放内存。

The pointer can be in one of the following states:

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

  • memory is not allocated (for example, pointer is null, or memory has been deallocated previously);
  • 内存未被分配(例如,指针为空,或者内存之前已被分配);
  • memory is allocated, but value has not been initialized;
  • 分配了内存,但是没有初始化值;
  • memory is allocated and value is initialized.
  • 分配内存并初始化值。

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

#1


4  

From Swift library UnsafeMutablePointer<T>

从斯威夫特图书馆UnsafeMutablePointer < T >

A pointer to an object of type T. This type provides no automated memory management, and therefore the user must take care to allocate and free memory appropriately.

指向t类型对象的指针不提供自动内存管理,因此用户必须小心分配和释放内存。

The pointer can be in one of the following states:

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

  • memory is not allocated (for example, pointer is null, or memory has been deallocated previously);
  • 内存未被分配(例如,指针为空,或者内存之前已被分配);
  • memory is allocated, but value has not been initialized;
  • 分配了内存,但是没有初始化值;
  • memory is allocated and value is initialized.
  • 分配内存并初始化值。

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