Another reason of C pointers are called unsafe is there is no auto memory management for them. We have to manage the memory in a behaviour prior to ARC, by allocating and releasing memory manually. If we failed to do the right things, the program will fail us with a crash or leak.

A correct way to begin to use a pointer from the beginning would be alloc it first and then initialize followed. After using it, we should take into consideration the fact that manually releasing is required. If not careful, it is easy to write like this:

This is wrong code

class MyClass {
    var a = 1
    deinit {
        print("deinit")
    }
}

var pointer: UnsafeMutablePointer<MyClass>!

pointer = UnsafeMutablePointer<MyClass>.alloc(1)
pointer.initialize(MyClass())

print(pointer.memory.a)  // Output: 1

pointer = nil

Although we set pointer to nil at last, UnsafeMutablePointer is not auto memory managed, the memory pointed by pointer is not released or collected. This can be proven by deinit of MyClass not get called. Notice: you have to run this code in a project other than in a Playground, which could not be used to check memory issues. The code above leaks memory. The correct way is adding destroy and dealloc to the end, which will release the pointed memory.

var pointer: UnsafeMutablePointer<MyClass>!

pointer = UnsafeMutablePointer<MyClass>.alloc(1)
pointer.initialize(MyClass())

print(pointer.memory.a)
pointer.destroy()
pointer.dealloc(1)
pointer = nil

// Output:
// 1
// deinit

If we try to access pointer or call dealloc on the pointer again after dealloc called, we will receive an EXC_BAD_ACCESS, which is not surprising at all. We are all aware of this kind of crash in the manually memory management age.

When handling memory management of these pointer types, we must follow a basic principle: the one who creates the pointer is responsible for releasing it. That means, dealloc and destroy should be used in pair with alloc and initialize respectively. If a pointer is not owned (created) by you, you are not expected to release it. A common case is that we get a pointer by calling a method, expect for explicitly mentioned in the documentation, you should not try to manage its memory state:

var x:UnsafeMutablePointer<tm>!
var t = time_t()
time(&t)
x = localtime(&t)
x = nil

At last, although we are using alloc and dealloc here, we can also use malloc or calloc to create the pointer. If so, we should use free instead of dealloc when releasing the pointer.

That's all. Good luck!