使用 FFTW 拆分数组时出现分段错误

Segmentation fault while using FFTW split arrays

我想使用 FFTW 拆分数据并查看其性能。因此,我根据在互联网上找到的一些示例编写了这个简单的程序。

代码如下:

#include <stdlib.h>
#include "defines.h"
#include <math.h>
#include <fftw3.h>

int main(void)
{ 
  double *Xre, *Xim, *Yre, *Yim;
  int N = 4096;
  int i =0, j=0;
  fftw_plan Plan;
  fftw_iodim Dim;

  Xre =  fftw_malloc(sizeof(double) * N);
  Xim =  fftw_malloc(sizeof(double) * N);
  Yre =  fftw_malloc(sizeof(double) * N);
  Yim =  fftw_malloc(sizeof(double) * N);

  for (i = 0; i < N; i++)
  {
    Xre[i] = input_data[2*i];
    Xim[i] = input_data[2*i+1];
  }
  if(!(Plan = fftw_plan_guru_split_dft(1, &Dim, 0, NULL,Xre, Xim, Yre, Yim, FFTW_ESTIMATE)))
    printf("FFTW3 failed to create plan.");

  fftw_execute_split_dft(Plan, Xre, Xim, Yre, Yim);

  printf("RESULTS:\n\n");
  for (j = 0; j < N; j++)
  {
    printf("RE: %f,\tIM: %f \n", Yre[j], Yim[j]);
  }
  fftw_destroy_plan(Plan);
  fftw_free(Xre);
  fftw_free(Xim);
  fftw_free(Yre);
  fftw_free(Yim);
  return 0;
}

其中 Xre 和 Xim 指的是实部和虚部的输入,Yre、Yim 是指结果。 input_data si 在 defines.h 文件中声明如下:

float input_data[8192] ={
-7.418860e-02,  1.188460e-03 ,  -1.612460e-02 ,  -7.506560e-02,
 7.372410e-02, -3.039230e-02 ,   4.457970e-02 ,   6.862750e-02,
-6.164490e-02,  5.634830e-02 ,  -6.556000e-02 ,  -5.147360e-02,
...          , ...           ,  ...           ,  ...           }            

我做了一些调试,似乎在执行行fftw_execute_split_dft(Plan, Xre, Xim, Yre, Yim)中出现了段错误。我读过这个 post 。但是,我仍然不明白这个错误背后的原因。

来自文档:

fftw_plan fftw_plan_guru_split_dft(
     int rank, const fftw_iodim *dims,
     int howmany_rank, const fftw_iodim *howmany_dims,
     double *ri, double *ii, double *ro, double *io,
     unsigned flags);

您看到 dims 作为 常量 指针传递。所以它需要用数组的实际维度进行初始化(并且库不能通过传递指针来计算数组的大小)

结构如下:

typedef struct {
     int n;
     int is;
     int os;
} fftw_iodim;

Here, n is the size of the dimension, and is and os are the strides of that dimension for the input and output arrays. (The stride is the separation of consecutive elements along this dimension.)

所以您的计划未正确初始化为随机数组大小。在创建计划之前,我会按如下方式初始化:

Dim.n = N;
Dim.is = 1;
Dim.os = 1;