如何使用UnsafeMutablePointer

时间:2023-01-23 21:23:21

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

我是Swift的新成员,我不知道如何使用UnsafeMutablePointer 。有人能帮助我吗? ?>

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.

我为TestStruct分配内存,但是当我传递ref给foo时,pointee指向nil。如果我将TestStruct (UnsafeMutablePointer )设置为非可选-一切都会运行良好- bar打印hello: 123。

UPDATE:

更新:

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

感谢@MartinR和@Hamish !工作代码:

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)

1 个解决方案

#1


1  

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.

赋值语句要求ptr。pointee处于初始化状态,指向TestClass实例。由于ARC(自动引用计数),在分配新值时释放先前指向的对象。如果ptr,崩溃。未初始化的指针数据。

#1


1  

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.

赋值语句要求ptr。pointee处于初始化状态,指向TestClass实例。由于ARC(自动引用计数),在分配新值时释放先前指向的对象。如果ptr,崩溃。未初始化的指针数据。