How to handle UnsafeMutablePointer correctly

I am a bit confused. When do I need to call for free, and when destroy / dealloc? I am working on a small piece of code studying basic sound. I thought that if I call UnsafeMutablePointer<Type>.alloc(size) , then I should call destroy and dealloc . But if I use malloc() or calloc() , I have to call free() .

In this Learning Core Audio example, the following code snippet makes me wonder:

 var asbds = UnsafeMutablePointer<AudioStreamBasicDescription>.alloc(Int(infoSize)) audioErr = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat, UInt32(sizeof(fileTypeAndFormat.dynamicType)), &fileTypeAndFormat, &infoSize, asbds) 

Here I use alloc . Free memory is called.

 free(asbds) 

But why not

 asbds.destroy(Int(infoSize)) asbds.dealloc(Int(infoSize)) 

which I would expect after the rule.

Any help would be appreciated because it makes my head spin. The documentation says that I am responsible for the destruction and release so that this part is clear, but how?

+6
source share
1 answer

See UnsafeMutablePointer Structure Link .

The pointer may be in one of the following states:

  • No memory is allocated (for example, the pointer is null, or the memory has been freed before).

  • Memory is allocated, but the value was not initialized.

  • The memory is allocated and the value is initialized.

You can safely use the marked area when "selected and initialized." So, if you want to use Swift UnsafeMutablePointer , you need to complete 2 steps before use and 2 steps after use.

(1) Highlight: alloc(_:) .

(2) Initialize: initialize...()

You can safely use the allocated and initialized area here.

(3) Deinitialize: destroy(_:)

(4) Cancel: dealloc(_:)


And why you can use free() for alloc(_:) ed memory, because Swift uses malloc(_:) in the current implementation of alloc(_:) . So using free means that your application depends on the current implementation of the Swift runtime.


So using UnsafeMutablePointer is something difficult and annoying. You should consider passing the array as a pointer. In your case, you can write something like the following:

  let elementCount = Int(infoSize) / strideof(AudioStreamBasicDescription) var asbds: [AudioStreamBasicDescription] = Array(count: elementCount, repeatedValue: AudioStreamBasicDescription()) audioErr = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat, UInt32(sizeof(fileTypeAndFormat.dynamicType)), &fileTypeAndFormat, &infoSize, &asbds) 

(I think you should use this elementCount even when using UnsafeMutablePointer . alloc(_:) or dealloc(_:) uses the "number of elements" rather than "byte size".)

+1
source

All Articles