1

I'm receiving one of these in a callback from an Objective-C library: UnsafeMutablePointer<UInt8>

I'm able to parse it. I'm also able to create one to send it back to the library, but: What are the risks of working with the "unsafe" type? How do I avoid those risks?

Also, the Objective-C library is using uint8_t * which bridges to Swift as this UnsafeMutablePointer<UInt8>... is this the best thing for Swift interop?

JAL
  • 41,701
  • 23
  • 172
  • 300
Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421

1 Answers1

5

UnsafeMutablePointer is how you represent a C pointer in Swift. It's unsafe because the underlying memory the pointer points to could change at anytime without the Swift pointer knowing. It also has no information about the size of the memory block that it points to (thanks Martin).

If your library requires you to use C types, in this case a pointer to a uint8_t, then you must use UnsafeMutablePointer. Otherwise I if you just want to represent an array of numbers I would wrap all of the uint8_t types in an NSArray as NSNumber types (or NSData if you are pointing to a byte stream) for easier bridging.

You can avoid these risks by dereferencing the pointer (if it is non-nil) and copying the value stored at the pointer to a variable in your Swift application.

JAL
  • 41,701
  • 23
  • 172
  • 300
  • Thank you, that WAS the question. – Dan Rosenstark Jun 22 '16 at 15:28
  • In my ignorance, I was basically worried that it would somehow present a leak. – Dan Rosenstark Jun 22 '16 at 15:31
  • 3
    It is also unsafe because the pointer has no information about the *size* of the memory block that it points to, and you can easily access invalid memory locations through the pointer. – Martin R Jun 22 '16 at 15:32
  • 1
    Great points Martin. @DanRosenstark it would only cause a leak if you `malloc` memory at the address of the pointer and don't `dealloc` or `destroy`, see [here](http://stackoverflow.com/q/36186540/2415822) for related discussion (ignore the autoreleasing pointers). – JAL Jun 22 '16 at 15:33
  • @JAL sorry to belabor the point: there is no risk that I would be doing unmatched `malloc` in Swift, correct? – Dan Rosenstark Jun 22 '16 at 19:21
  • @DanRosenstark if the SDK you are using is just passing you a pointer, you are in the clear. – JAL Jun 22 '16 at 19:24
  • @JAL what about if I am passing to the SDK, using `UnsafeMutablePointer.alloc(27)` to create it? – Dan Rosenstark Jun 22 '16 at 20:16
  • @DanRosenstark I might need more context. If you're calling `malloc` or `alloc` without calling `free`, that's definitely a point where a memory leak could occur. What does this SDK do? – JAL Jun 22 '16 at 20:18
  • The SDK speaks MIDI over a wire. I still have control of the object and could call `destroy` if that's what necessary. – Dan Rosenstark Jun 22 '16 at 20:20
  • @DanRosenstark if you manage the memory that the pointer points to, then I would explicitly call `destroy`. Just make sure the SDK cleans itself up before destroying the pointer. You don't want that SDK thinking that the memory is still available after the pointer has been destroyed on the application side. – JAL Jun 22 '16 at 20:21
  • 1
    Okay, thanks so much for your patience and generosity with explaining all this. Respect! – Dan Rosenstark Jun 22 '16 at 20:23
  • @MartinR thanks! "Access invalid memory locations" and crash, get incorrect data, or both/neither? – Dan Rosenstark Jun 22 '16 at 20:43
  • 1
    @DanRosenstark potentially all of the above. – JAL Jun 22 '16 at 20:45