使用3D数组对线性索引宏进行三维Poisson乘法时的分段错误

时间:2018-06-19 15:04:57

标签: c multidimensional-array macros segmentation-fault

我希望有人可以提供以下帮助,但我不知道出了什么问题。下面的函数用于使用3D拉普拉斯算子将3维矩阵和向量相乘,尽管这对于了解此问题不是必需的。我在函数的开头创建了两个宏,以从3D几何空间映射到线性存储空间。

使用宏从X(i,j-1,k)访问元素X(0,0,0)时出现分段错误,即当电流循环为i = 0,j = 1时对于具有n_x,n_y和n_z = 100(100x100x100)的系统,,k = 0,(0,1,0)。因此,宏会将3D几何形状(0,0,0)更改为线性索引0,可以通过打印确认。打印时访问x [0]很好。并且打印宏的结果也为零。

抱歉,我可能对宏的理解很简单?我正在使用动态内存分配数组。

void matvec_mul(int N,int n_x, int n_y, int n_z,double* restrict Ax,double* restrict x){
 #define X(i,j,k) (x[(i*n_y*n_z)+(j*n_z)+k])
 #define AX(i,j,k) (Ax[(i*n_y*n_z)+(j*n_z)+k])
 int inv_h2 = (n_x-1)*(n_x-1);
 for (int i = 0; i < n_x; ++i) {
  for (int j = 0; j < n_y; ++j) {
   for (int k = 0; k < n_z; ++k) {
    printf("%i,%i,%i\n",i,j,k);
    printf("%i\n",(i*n_y*n_z)+(j*n_z)+k);
    double xx = X(i,j,k);
    double xn = (i > 0) ? X(i-1,j,k) : 0;
    double xs = (i < n_x-1) ? X(i+1,j,k) : 0;
    printf("Seg faults on next line\n");
    double xe = (j > 0) ? X(i,j-1,k) : 0;
    double xw = (j < n_y-1) ? X(i,j+1,k) : 0;
    double xu = (k > 0) ? X(i,j,k-1) : 0;
    double xd = (k < n_z-1) ? X(i,j,k+1) : 0;
    AX(i,j,k) = (6*xx - xn - xs - xe - xw - xu - xd)/inv_h2;
   }
  }
 }
#undef AX
#undef X
}

1 个答案:

答案 0 :(得分:1)

问题是由于宏替换文本中的宏参数周围没有括号。

将宏定义更改为以下内容:

#define X(i,j,k) (x[((i)*n_y*n_z)+((j)*n_z)+(k)])
#define AX(i,j,k) (Ax[((i)*n_y*n_z)+((j)*n_z)+(k)])

使用您的原始宏,X(i,j-1,k)将扩展为(x[(i*n_y*n_z)+(j-1*n_z)+k]),但您需要(x[(i*n_y*n_z)+((j-1)*n_z)+k])。 (请注意(j-1*n_z)((j-1)*n_z)之间的区别。)使用新的宏,替换为(x[((i)*n_y*n_z)+((j-1)*n_z)+(k)])