FFTW计划分段错误
FFTW plan segmentation fault
我正在使用 FFTW3 对多列数据执行 fft(即多通道音频,我希望对每个通道进行转换)。这在 OSX 上运行良好,但将代码移植到 linux 时出现段错误。
const int fftwFlags = FFTW_PRESERVE_INPUT|FFTW_PATIENT;
struct fft {
fftw_complex **complexSig;
double **realSig;
fftw_plan forwardR2C;
int fftLen;
int numChan;
}
void create FFT(struct fft *fft) {
int bufLen = 1024;
int numChan = 4;
fft->fftLen = bufLen;
fft->numChan = numChan;
fft->realSig = fftw_malloc(sizeof(double *) * numChan);
for(int i = 0; i < numChan; i++) {
fft->realSig[i] = fftw_malloc(sizeof(double) * bufLen);
}
fft->complexSig = fftw_malloc(sizeof(fftw_complex *) * numChan);
for(int i = 0; i < numChan; i++) {
fft->complexSig[i] = fftw_malloc(sizeof(fftw_complex) * bufLen);
}
fft->forwardR2C = fftw_plan_many_dft_r2c(1, &fft->fftLen, fft->numChan, *fft->realSig, &fft->fftLen, 1, fft->fftLen, *fft->complexSig, &fft->fftLen, 1, fft->fftLen, fftwFlags);
}
valgrind 显示 fftw 规划器试图访问此数组的末尾(8 个字节,一个样本),导致分段错误。当将分配给 realSig 的内存量增加到 bufLen * 2 时,此错误不存在。
我确信这是我告诉 FFTW 读取我的数据的方式的错误,但我无法发现它!
您似乎假设连续的 malloc 调用将是连续的,当然它们不太可能是连续的(您可能只是 "got lucky" 在 OS X 上)。你可以很容易地解决这个问题,但是通过做一个大的分配,例如
void createFFT(struct fft *fft)
{
const int bufLen = 1024;
const int numChan = 4;
fft->fftLen = bufLen;
fft->numChan = numChan;
fft->realSig = fftw_malloc(sizeof(double *) * numChan);
// array of numChan pointers
fft->realSig[0] = fftw_malloc(sizeof(double) * numChan * bufLen);
// one large contiguous block of size `numChan * bufLen`
for(int i = 1; i < numChan; i++) // init pointers
{
fft->realSig[i] = fft->realSig[i - 1] + bufLen;
}
// ...
}
注意:完成后您只需:
fftw_free(fft->realSig[0]);
我正在使用 FFTW3 对多列数据执行 fft(即多通道音频,我希望对每个通道进行转换)。这在 OSX 上运行良好,但将代码移植到 linux 时出现段错误。
const int fftwFlags = FFTW_PRESERVE_INPUT|FFTW_PATIENT;
struct fft {
fftw_complex **complexSig;
double **realSig;
fftw_plan forwardR2C;
int fftLen;
int numChan;
}
void create FFT(struct fft *fft) {
int bufLen = 1024;
int numChan = 4;
fft->fftLen = bufLen;
fft->numChan = numChan;
fft->realSig = fftw_malloc(sizeof(double *) * numChan);
for(int i = 0; i < numChan; i++) {
fft->realSig[i] = fftw_malloc(sizeof(double) * bufLen);
}
fft->complexSig = fftw_malloc(sizeof(fftw_complex *) * numChan);
for(int i = 0; i < numChan; i++) {
fft->complexSig[i] = fftw_malloc(sizeof(fftw_complex) * bufLen);
}
fft->forwardR2C = fftw_plan_many_dft_r2c(1, &fft->fftLen, fft->numChan, *fft->realSig, &fft->fftLen, 1, fft->fftLen, *fft->complexSig, &fft->fftLen, 1, fft->fftLen, fftwFlags);
}
valgrind 显示 fftw 规划器试图访问此数组的末尾(8 个字节,一个样本),导致分段错误。当将分配给 realSig 的内存量增加到 bufLen * 2 时,此错误不存在。
我确信这是我告诉 FFTW 读取我的数据的方式的错误,但我无法发现它!
您似乎假设连续的 malloc 调用将是连续的,当然它们不太可能是连续的(您可能只是 "got lucky" 在 OS X 上)。你可以很容易地解决这个问题,但是通过做一个大的分配,例如
void createFFT(struct fft *fft)
{
const int bufLen = 1024;
const int numChan = 4;
fft->fftLen = bufLen;
fft->numChan = numChan;
fft->realSig = fftw_malloc(sizeof(double *) * numChan);
// array of numChan pointers
fft->realSig[0] = fftw_malloc(sizeof(double) * numChan * bufLen);
// one large contiguous block of size `numChan * bufLen`
for(int i = 1; i < numChan; i++) // init pointers
{
fft->realSig[i] = fft->realSig[i - 1] + bufLen;
}
// ...
}
注意:完成后您只需:
fftw_free(fft->realSig[0]);