2017-07-07 93 views
1

我试图使用Swift Accelerate库中的vDSP_ctoz将交错的DSPComplex向量转换为DSPSplitComplex向量。下面的代码的最后一行产生错误Segmentation fault: 11使用Swift Accelerate的分段错误vDSP_ctoz

我不明白为什么vDSP_ctoz会尝试访问超出界限的内存时,我已经分配了大型向量,只是试图处理少量的元素。载体是大小2048和在vDSP_ctozN(数量的元件来处理的)的参数是1

我打电话vDSP_ctoz时,没有效果使用不同的步幅和N值也尝试。

// set stride values 
let dspComplexStride = MemoryLayout<DSPComplex>.stride 
let dspSplitComplexStride = MemoryLayout<DSPSplitComplex>.stride 

// make interleaved vector 
var interleaved = UnsafeMutablePointer<DSPComplex>.allocate(capacity: 2048) 
for index in 0..<16 { 
    interleaved[index] = DSPComplex(real: Float(2*index), imag: Float(2*index+1)) 
} 

// make split vector 
var splitComplex = UnsafeMutablePointer<DSPSplitComplex>.allocate(capacity: 2048) 
vDSP_ctoz(
    interleaved, dspComplexStride, splitComplex, dspSplitComplexStride, 1 
) 

回答

2

DSPSplitComplex是含有指针阵列的结构, 所以需要一个单一的DSPSplitComplex元素和必须分配 存储其realpimagp和性质。

“stride”参数不是以字节为单位,而是以“元素”单位进行度量。 所以你通过__IZ == 1是因为你想在目标数组中填充连续元素 。

它可能不是显而易见的是,你必须通过__IC == 2用于源阵列,即 源阵列的步幅在Float单元,而不是在 DSPComplex单位给出。这可以从vDSP_ctoz documentation 其中提到的是,有效地发挥作用确实

for (n = 0; n < N; ++n) 
{ 
    Z->realp[n*IZ] = C[n*IC/2].real; 
    Z->imagp[n*IZ] = C[n*IC/2].imag; 
} 

最后被推断,的vDSP_ctoz的最后一个参数是元件以 过程的数目。

全部放在一起,这是它如何工作:

import Accelerate 

let N = 16 

var interleaved = UnsafeMutablePointer<DSPComplex>.allocate(capacity: N) 
for index in 0..<N { 
    interleaved[index] = DSPComplex(real: Float(2*index), imag: Float(2*index+1)) 
} 

let realp = UnsafeMutablePointer<Float>.allocate(capacity: N) 
let imagp = UnsafeMutablePointer<Float>.allocate(capacity: N) 
var splitComplex = DSPSplitComplex(realp: realp, imagp: imagp) 

vDSP_ctoz(interleaved, 2, &splitComplex, 1, vDSP_Length(N)) 

for index in 0..<N { 
    print(splitComplex.realp[index], splitComplex.imagp[index]) 
} 

,当然最终你必须要释放内存。