vDSP_fft_zip返回的UnsafeMutablePointer <float>立即被覆盖

时间:2018-10-10 10:17:14

标签: swift vdsp unsafemutablepointer

在Swift 4中,我正在创建要在vDSP_fft_zip()中使用的DSPSplitComplex,但是下次我创建另一个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

我想线索可能在标题“不安全”中,但是如果它实际上不可用,那么存储返回的DSPSplitComplex内容的正确策略是什么?

我猜想从它们创建新的[Float]数组是制作永久副本的一种方法

let arrary = Array(UnsafeBufferPointer(start: splitComplex1.realp, count: 32))

...但似乎,尽管阅读了Swift文档,但我仍然误解了UnsafeMutablePointer的要点,因为为什么vDSP_fft_zip()会返回一开始就无法使用的内容?

1 个答案:

答案 0 :(得分:2)

您创建DSPSplitComplex的方式是错误的。

使用Array<Float>UnsafeMutablePointer<Float>传递到&时,传递给函数的地址仅在函数内有效。

因此,在您的代码中,DSPSplitComplex(realp: &A, imagp: &B)的初始化程序完成后,传递给DSPSplitComplex的两个地址无效。

为避免这种行为,您可以尝试如下操作:

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>