使用Swift Accelerate的分段错误vDSP_ctoz
问题描述:
我试图使用Swift Accelerate库中的vDSP_ctoz
将交错的DSPComplex
向量转换为DSPSplitComplex
向量。下面的代码的最后一行产生错误Segmentation fault: 11
使用Swift Accelerate的分段错误vDSP_ctoz
我不明白为什么vDSP_ctoz
会尝试访问超出界限的内存时,我已经分配了大型向量,只是试图处理少量的元素。载体是大小2048和在vDSP_ctoz
为N
(数量的元件来处理的)的参数是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
)
答
DSPSplitComplex
是含有指针阵列的结构, 所以需要一个单一的DSPSplitComplex
元素和必须分配 存储其realp
imagp
和性质。
“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])
}
,当然最终你必须要释放内存。