vDSP_fft_zip 返回的 UnsafeMutablePointer<Float> 被立即覆盖
UnsafeMutablePointer<Float> returned by vDSP_fft_zip being overwritten immediately
在 Swift 4 中,我正在创建一个 DSPSplitComplex 以在 vDSP_fft_zip() 中使用,但下次我创建另一个 DSPSplitComplex 时它会立即被覆盖。
( DSPSplitComplex 结构有 2 UnsafeMutablePointer<Float>
)
//--Create the DSPSplitComplex
var A = [Float](repeating:0, count:32);
var B = [Float](repeating:0, count:32)
var splitComplex1 = DSPSplitComplex(realp: &A, imagp: &B)
//--Perform fft
log2Size = vDSP_Length(log2f(Float(32)))
setupFFT = vDSP_create_fftsetup(log2Size, FFTRadix(FFT_RADIX2))!;
vDSP_fft_zip(setupFFT, & splitComplex1, 1, log2Size, FFTDirection(FFT_FORWARD));
//--Create another DSPSplitComplex
var C = [Float](repeating:0, count:32);
var D = [Float](repeating:0, count:32)
var splitComplex2 = DSPSplitComplex(realp: &C, imagp: &D)
我现在可以在调试器中看到 splitComplex2.realp
的 UnsafeMutablePointer 与 splitComplex1.realp
的地址相同,因此我对 splitComplex2 所做的任何操作都会覆盖 splitComplex1
我猜线索可能在标题中 'unsafe',但如果它实际上无法使用,那么存储 returned DSPSplitComplex 内容的正确策略是什么?
我想从它们创建新的 [Float] 数组是制作永久副本的一种方法
let arrary = Array(UnsafeBufferPointer(start: splitComplex1.realp, count: 32))
...但看起来,尽管阅读了 Swift 文档,我仍然误解了 UnsafeMutablePointer 的要点,因为为什么 vDSP_fft_zip() return 是get-go?
无法使用
你的创建方式DSPSplitComplex
是错误的。
当您使用&
将Array<Float>
传递给UnsafeMutablePointer<Float>
时,传递给函数的地址仅在函数内有效。
因此,在您的代码中,当 DSPSplitComplex
的初始化程序完成时,传递给 DSPSplitComplex(realp: &A, imagp: &B)
的两个地址无效。
要避免这种行为,您可以尝试这样的操作:
var A = [Float](repeating:0, count:32)
var B = [Float](repeating:0, count:32)
A.withUnsafeMutableBufferPointer {aumbp in
B.withUnsafeMutableBufferPointer {bumbp in
var splitComplex1 = DSPSplitComplex(realp: aumbp.baseAddress!, imagp: bumbp.baseAddress!)
//--Perform fft
let log2Size = vDSP_Length(log2f(Float(32)))
let setupFFT = vDSP_create_fftsetup(log2Size, FFTRadix(FFT_RADIX2))!
vDSP_fft_zip(setupFFT, &splitComplex1, 1, log2Size, FFTDirection(FFT_FORWARD))
}
}
否则,您可以分配 UnsafeMutableBufferPointer<Float>
并使用它们代替 Array<Float>
。
在 Swift 4 中,我正在创建一个 DSPSplitComplex 以在 vDSP_fft_zip() 中使用,但下次我创建另一个 DSPSplitComplex 时它会立即被覆盖。
( DSPSplitComplex 结构有 2 UnsafeMutablePointer<Float>
)
//--Create the DSPSplitComplex
var A = [Float](repeating:0, count:32);
var B = [Float](repeating:0, count:32)
var splitComplex1 = DSPSplitComplex(realp: &A, imagp: &B)
//--Perform fft
log2Size = vDSP_Length(log2f(Float(32)))
setupFFT = vDSP_create_fftsetup(log2Size, FFTRadix(FFT_RADIX2))!;
vDSP_fft_zip(setupFFT, & splitComplex1, 1, log2Size, FFTDirection(FFT_FORWARD));
//--Create another DSPSplitComplex
var C = [Float](repeating:0, count:32);
var D = [Float](repeating:0, count:32)
var splitComplex2 = DSPSplitComplex(realp: &C, imagp: &D)
我现在可以在调试器中看到 splitComplex2.realp
的 UnsafeMutablePointer 与 splitComplex1.realp
的地址相同,因此我对 splitComplex2 所做的任何操作都会覆盖 splitComplex1
我猜线索可能在标题中 'unsafe',但如果它实际上无法使用,那么存储 returned DSPSplitComplex 内容的正确策略是什么?
我想从它们创建新的 [Float] 数组是制作永久副本的一种方法
let arrary = Array(UnsafeBufferPointer(start: splitComplex1.realp, count: 32))
...但看起来,尽管阅读了 Swift 文档,我仍然误解了 UnsafeMutablePointer 的要点,因为为什么 vDSP_fft_zip() return 是get-go?
无法使用你的创建方式DSPSplitComplex
是错误的。
当您使用&
将Array<Float>
传递给UnsafeMutablePointer<Float>
时,传递给函数的地址仅在函数内有效。
因此,在您的代码中,当 DSPSplitComplex
的初始化程序完成时,传递给 DSPSplitComplex(realp: &A, imagp: &B)
的两个地址无效。
要避免这种行为,您可以尝试这样的操作:
var A = [Float](repeating:0, count:32)
var B = [Float](repeating:0, count:32)
A.withUnsafeMutableBufferPointer {aumbp in
B.withUnsafeMutableBufferPointer {bumbp in
var splitComplex1 = DSPSplitComplex(realp: aumbp.baseAddress!, imagp: bumbp.baseAddress!)
//--Perform fft
let log2Size = vDSP_Length(log2f(Float(32)))
let setupFFT = vDSP_create_fftsetup(log2Size, FFTRadix(FFT_RADIX2))!
vDSP_fft_zip(setupFFT, &splitComplex1, 1, log2Size, FFTDirection(FFT_FORWARD))
}
}
否则,您可以分配 UnsafeMutableBufferPointer<Float>
并使用它们代替 Array<Float>
。