How to use UnsafeMutablePointer<T?> in swift 3

0xAT

I'm new to Swift and i don't understand how to use UnsafeMutablePointer<T?>. Could anyone help me?

struct TestStruct {
    var a = 0
}

func foo(ptr: UnsafeMutablePointer<TestStruct?>?) {
    ptr?.pointee?.a = 123 // pointee is nil, but why?
}

func bar(ptr: TestStruct?) {
    print("hello: \(ptr?.a)") // hello: nil
}

var ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)

foo(ptr: ref)
bar(ptr: ref.pointee)

ref.deallocate(capacity: 1)

I'm allocate memory for the TestStruct, but when i pass ref to the foo, pointee points to the nil. If i will make TestStruct ( UnsafeMutablePointer<TestStruct> ) non-optional - everything will work great - bar prints hello: 123.

UPDATE:

Thanks to the @MartinR and @Hamish ! Working code:

struct TestStruct {
    var a = 0
}

func foo(ptr: UnsafeMutablePointer<TestStruct?>?) {
    ptr?.pointee?.a = 123
}

func bar(ptr: TestStruct?) {
    print("hello: \(ptr?.a)")
}

var ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)

ref.initialize(to: TestStruct())

foo(ptr: ref)
bar(ptr: ref.pointee)


ref.deinitialize()
ref.deallocate(capacity: 1)
Martin R

The behaviour of your program is undefined.

allocate() returns uninitialized memory:

/// Allocates and points at uninitialized aligned memory for `count`
/// instances of `Pointee`.
///
/// - Postcondition: The pointee is allocated, but not initialized.
public static func allocate(capacity count: Int) -> UnsafeMutablePointer<Pointee>

You have to initialize it before use (and deinitialize before freeing the memory):

let ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)
ref.initialize(to: TestStruct())

foo(ptr: ref)
bar(ptr: ref.pointee)

ref.deinitialize()
ref.deallocate(capacity: 1)

Here is another example where not initializing the memory actually leads to a crash:

class TestClass {
    init() { print("init") }
    deinit { print("deinit") }
}

let ptr = UnsafeMutablePointer<TestClass>.allocate(capacity: 1)
ptr.pointee = TestClass()

The assignment statement expects that ptr.pointee is in the initialized state and points to a TestClass instance. Because of ARC (automatic reference counting), the previously pointed-to object is released when assigning a new value. That crashes if ptr.pointee is uninitialized.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to use UnsafeMutablePointer in Swift 3?

How to use UnsafeMutablePointer<OpaquePointer> in Swift?

Convert UnsafeMutableRawPointer to UnsafeMutablePointer<T> in swift 3

How to create UnsafeMutablePointer<UnsafeMutablePointer> in swift

UnsafeMutablePointer<CFTypeRef> in Swift 3

UnsafeMutablePointer to expected argument type UnsafeMutablePointer<_> in Swift 3

How to do pointer arithmetic on UnsafeMutablePointer and get String in Swift 3

How to convert String to UnsafeMutablePointer<UInt8> ? Swift 3

Error in UnsafeMutablePointer in swift3

UnsafeMutablePointer<Bytef> swift3

Can´t get the SecKey UnsafeMutablePointer in iOS Swift

Convert String to UnsafeMutablePointer<char_t> in Swift

Casting a variable of type 'UnsafeMutableRawPointer' to UnsafeMutablePointer<> in Swift 3

How to convert a type of "any" in kind "UnsafeMutablePointer<Int16>" in a swift 3

How to create UnsafeMutablePointer<CGPoint> Object in swift

How to cast self to UnsafeMutablePointer<Void> type in swift

How to dealloc UnsafeMutablePointer referenced from Swift struct

how to loop through elements of array of <UnsafeMutablePointer> in Swift

Swift UnsafeMutablePointer & UnsafeMutablePointer<UnsafePointer<SomeType>>

How to use the Swift 3 selectors?

How to use unsafeDowncast in Swift 3

How to use XCTestSuite? (Swift 3)

How to use NSTimeInterval in Swift 3

How to use autocompleteBounds in swift 3

How to get length of a UnsafeMutablePointer<Object> written to a OpenSSL BIO in Swift?

How to cast UnsafeMutableRawPointer! to UnsafeMutablePointer<Float> in Swift 3.0 or newer?

How to create a UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>

How to use my static library (.a) in swift 3

How to use Process() in Swift 3 for Linux?