1

I am using a variable inside a function with holds and UnsafeMutablePointer<objc_property_t>. Should I call free on it?

func logProps() {
    var count: UInt32 = 0
    let _propArr = class_copyPropertyList(cls, &count)
    // ...
    // free(propArr)  // ?
}

On a different note, is free same as using deallocate (Swift UnsafeMutablePointer: Must I call deinitialize before deallocate?) ?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
John Doe
  • 2,225
  • 6
  • 16
  • 44

1 Answers1

3

Yes, because of the name of the method. class_copyPropertyList includes the word "copy" which indicates that the buffer belongs to you. Note that the documentation also indicates this:

You must free the array with free().

So you should use free() to destroy this buffer. This is currently identical to calling .deallocate(), but that is not promised, so follow the instructions as given.

(Thanks to MartinR for running down the question of free vs deallocate.)

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 2
    *"... the C function free is called deallocate in Swift"* – not really. The C function `free()` still exists under that name. `deallocate()` is a method of UnsafeMutablePointer (the counterpart of `allocate()`) which calls `Builtin.deallocRaw`, which *might* be the same as or compatible to `free()`, but that is not documented. – Martin R Mar 17 '19 at 15:26
  • @MartinR I struggled a lot writing that, and still don't have the right answer in my head. Do we know that calling `free` is promised to be correct in a way that we don't know calling `.deallocate` is? The documentation for class_copyPropertyList says to use `free()`, but it also says that it returns NULL, which doesn't exist in Swift. My point being these docs aren't explaining Swift; we're expected to make Swift translations. So should we take "call free" to mean literally "call free" or "deallocate the UnsafeMuatablePointer?" If free/deallocate diverge, which would be correct Swift? – Rob Napier Mar 17 '19 at 16:02
  • My gut feeling is that there should be no case where `.deallocate` is wrong to deallocate the pointer's uninitialized/trivial memory. The docs for `.deallocate` do not say "that was allocated with `.allocate`. They say "Deallocates the memory block previously allocated at this pointer." (But I'm not completely certain about this; I'm just trying to nail down what practice we should be adopting and how we should know.) – Rob Napier Mar 17 '19 at 16:04
  • 2
    If class_copyPropertyList says to use free() then we can assume that the memory is allocated with malloc(). The return value is an optional, and C NULL pointers are mapped to nil in Swift. I would follow the docs and use free, but I do not know if it makes a difference. – I am still struggling to find out what Builtin.deallocRaw actually *does.* – Martin R Mar 17 '19 at 16:13
  • 2
    Let's ask the experts: https://forums.swift.org/t/unsafemutablepointer-allocation-compatibility-with-c-malloc-free/21713 – Martin R Mar 17 '19 at 16:34
  • 1
    @MartinR Thanks for running this down. I've fixed the answer. – Rob Napier Mar 17 '19 at 19:47