【问题标题】:C array memory deallocation from swift来自 swift 的 C 数组内存释放
【发布时间】:2014-12-21 03:58:56
【问题描述】:
var cpuInfo: processor_info_array_t = nil
var numCpuInfo: mach_msg_type_number_t = 0
var coresTotalUsage: Float = 0.0
var numCPUsU: natural_t = 0
let err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
assert(err == KERN_SUCCESS, "Failed call to host_processor_info")

您好,我正在调用上述 C API host_processor_info 以从 swift 获取进程加载信息,那里没有问题。 cpuInfo 是一个 inout 参数(指针),返回时将指向一个包含由该 API 分配的 CPU 信息的结构。 调用者负责释放内存;我可以从目标 C 轻松做到这一点,但在 swift 中没有任何运气。我知道我可以将该调用包装到一个客观的 C 扩展中,但我正在努力学习 swift 并且希望,如果可能的话,避免使用 obj-c 解决方案。

在 obj-c 中,我会使用:

size_t cpuInfoSize = sizeof(integer_t) * numCpuInfo;
vm_deallocate(mach_task_self(), (vm_address_t) cpuInfo, cpuInfoSize)

swift 中的 cpuInfo 是 UnsafeMutablePointer 不能转换为 vm_address_t。

任何帮助表示赞赏,谢谢。

【问题讨论】:

    标签: ios macos swift interop xcode6


    【解决方案1】:

    在 Swift 4 中,等效代码似乎是:

    let cpuInfoSize = vm_size_t(MemoryLayout<integer_t>.stride * Int(numCpuInfo))
    vm_deallocate(mach_task_self_, vm_address_t(bitPattern: cpuInfo), cpuInfoSize)
    

    特别是,初始化器UInt(bitPattern:) 现在显然比unsafeBitCast() 更喜欢用指针的位模式初始化无符号整数(我猜这种用法不再被认为是“不安全的”)。它正确处理了nil 指针,在这种情况下返回 0。

    【讨论】:

      【解决方案2】:

      processor_info_array_t是指针类型,vm_address_t是整数类型 (最终是UInt 的别名)。 (从&lt;i386/vm_types.h&gt;的cmets来看 这可能是出于历史原因。) 在 Swift 中将指针转换为整数(大小相同)的唯一方法是 unsafeBitCast。

      mach_init.h 定义

      extern mach_port_t      mach_task_self_;
      #define mach_task_self() mach_task_self_
      

      在 Swift 中只有 extern 变量可见,宏不可见。

      这给出了:

      let cpuInfoSize = vm_size_t(sizeof(integer_t)) * vm_size_t(numCpuInfo)
      vm_deallocate(mach_task_self_, unsafeBitCast(cpuInfo, vm_address_t.self), cpuInfoSize)
      

      【讨论】:

      • var prevCpuInfoSize: vm_size_t = UInt(UInt32(sizeof(integer_t)) * numPrevCpuInfo) as vm_size_t vm_deallocate(mach_task_self_, unsafeBitCast(prevCpuInfo, vm_address_t.self), prevCpuInfoSize) 谢谢马丁!小的修改,但几乎可以工作,没有更多的内存泄漏。我不太明白为什么只有 extern 变量在 swift 中可见,而在宏中不可见。
      • @Pippo:有些(Objective-)C 宏是导入的,有些不是,比较stackoverflow.com/questions/24325477/…。
      • @Pippo:你说得对,我忘了乘法。我已经更新了答案,作为未来读者的参考。
      • 这在 Swift 3.1 中仍然有效。只想说声谢谢,马丁!
      • @lightpen:很高兴知道,感谢您的确认!
      猜你喜欢
      • 2015-09-10
      • 2015-09-05
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      相关资源
      最近更新 更多