Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If a function returns an UnsafeMutablePointer is it our responsibility to destroy and dealloc?

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:

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?

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)

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


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 StackOverflow, Apple Dev Forums, Twitter and Apple's old documentation on allocating memory and releasing it, pre-ARC. See here.

like image 427
sketchyTech Avatar asked Sep 01 '14 12:09

sketchyTech


1 Answers

From Swift library 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.

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 { /**/}

like image 161
Maxim Shoustin Avatar answered Nov 18 '22 14:11

Maxim Shoustin