If a Function Returns an Unsafemutablepointer Is It Our Responsibility to Destroy and Dealloc

If a function returns an UnsafeMutablePointer is it our responsibility to destroy and dealloc?

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

Do I need to release an UnsafeBufferPointer, or the UnsafePointer used at the buffer pointer's starting memory location?

UnsafePointer(self.bytes) is only a pointer conversion from UnsafePointer<Void> to UnsafePointer<UInt8> (like a "cast" in C). It does not allocate memory.

The memory is managed by the NSData object. You did not alloc() the
memory and therefore must not call dealloc() on the pointer.
You also did not initialize() the memory and therefore must not
destroy() it.

How to dealloc UnsafeMutablePointer referenced from Swift struct

You could wrap the pointer in a class. Something like this:

struct ViewBox {
class WrappedPointer() {
let pointer: UnsafeMutablePointer<UIView>

init() {
pointer = UnsafeMutablePointer<UIView>.alloc(1)
}

deinit {
pointer.dealloc(1)
}
}

let wrappedPointer = WrappedPointer()
}

nsobject dealloc never called

You might want to enclose the inner loop with an @autoreleasepool { ... } which tells the compiler when to do the disposal, otherwise the pool will only be emptied when control returns to the main loop.

for (i = 0; i < 10; i++) {
@autoreleasepool {
...
}
}

As pointed out by CodeFi in the comments:
This will create a new autoreleasepool for each iteration of the loop, which would destroy each object after the iteration is completed, but would make the program do more work. If you don't mind all the objects hanging around until after the loop is completed, you would put the @autoreleasepool outside of the outer loop

@autoreleasepool {
for (i = 0; i < 10; i++) {
...
}
}

The initial values of static variables may not even match what’s specified in the source code

I replaced MY_HEAP = Some(...) with core::ptr::write(&mut MY_HEAP, Some(...)) and problem was resolved.

pub struct Heap {
pub vector: Vec<u8>,
}

pub static mut MY_HEAP: Option<Heap> = None;

fn main() {
unsafe {
assert!(MY_HEAP.is_none());
}
unsafe {
core::ptr::write(
&mut MY_HEAP,
Some(Heap {
vector: vec![1, 2, 3],
}),
);
};
unsafe {
match &mut MY_HEAP {
Some(h) => {
println!("{:?}", h.vector);
}
None => (),
}
}
}

Thanks to trent ᶠᵒʳᵐᵉʳˡʸ ᶜˡ



Related Topics



Leave a reply



Submit