ios - 使用 UnsafeMutablePointer 访问释放的内存
问题描述
我对UnsafeMutablePointer
.
以下代码按预期崩溃,因为我们试图访问已经被释放的内存。
let storage = UnsafeMutablePointer<[UInt8]>.allocate(capacity: 1)
// initialize
storage.initialize(to: [0x01])
storage.deinitialize(count: 1)
storage.deallocate()
print(storage) // 0x00007ff236404890
print(storage.pointee) // Will Crash EXC_BAD_ACCESS
将类型更改为 Bool 不会使应用程序崩溃,我们可以读取指针值。为什么会这样?
let storage = UnsafeMutablePointer<Bool>.allocate(capacity: 1)
// initialize
storage.initialize(to: false)
storage.deinitialize(count: 1)
storage.deallocate()
print(storage) // 0x00007ff236404890
print(storage.pointee) // false
解决方案
@jckarter 在 Twitter 上为我回答了这个问题。
因此,首先在直接使用内存时使用地址清理器总是好的。
在释放内存后访问内存是未定义的行为。因此,可能会发生多种事情,我们不能依赖于此。
这种行为是因为:
当您释放内存时,它不一定会立即返回到操作系统,因为在需要新分配之前将内存保持原样会更有效。因此,您可能可以在内存释放后的某个时间访问旧值,但您不能依赖它。
使用诸如 Address Sanitizer 或 Guard Malloc 之类的内存检查工具应该使行为更可预测,因为它们增加了对释放后使用的内存的更多检查
--@jckarter
启用地址清理程序时的说明:
let storage = UnsafeMutablePointer<Bool>.allocate(capacity: 1)
// initialize
storage.initialize(to: false)
storage.deinitialize(count: 1)
storage.deallocate()
print(storage)
print(storage.pointee) // Thread 1: Use of deallocated memory ❗️