17

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.

Community
  • 1
  • 1
sketchyTech
  • 5,137
  • 28
  • 52

1 Answers1

4

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

Maxim Shoustin
  • 76,444
  • 28
  • 192
  • 219
  • @GoodbyeStackOverflow in swift lang you don't need allocate memory for instances, however from Swift they tell you need to allocate for `UnsafeMutablePointer`. – Maxim Shoustin Sep 01 '14 at 12:49
  • I've been looking at UnsafeMutablePointers and wrote a blogpost on allocating and initialising, then destroying and deallocating. But the reason for this Q was because I was uncertain of what happens when one is returned rather than directly created. – sketchyTech Sep 01 '14 at 13:18