0

我需要在 C 中构建两个 3D 连续数组(注意x0x)。尺寸必须是x[size_tot_y][size_tot_x][size_tot_z]和。x0[size_tot_y][size_tot_x][size_tot_z]这是我的代码:

  double*** x;
  double** x_val2;

  double*** x0;
  double** x0_val2;

  x0 = malloc(size_tot_y*sizeof(double**));
  x0_val2 = malloc(size_tot_x*size_tot_y*size_tot_z*sizeof(double*));

  x = malloc(size_tot_y*sizeof(double**));
  x_val2 = malloc(size_tot_x*size_tot_y*size_tot_z*sizeof(double*));

  for(j=0;j<=size_tot_y-1;j++) {    
      x0[j] = &x0_val2[j*size_tot_x*size_tot_z];
      x[j] = &x_val2[j*size_tot_x*size_tot_z];
      }

  for(i=0;i<=size_tot_y-1;i++) {
      for(j=0;j<=size_tot_x-1;j++) {
          x0[i][j] = malloc(size_tot_z*sizeof(double));
      x[i][j] = malloc(size_tot_z*sizeof(double));
      }
     }

  for(i=0;i<=size_tot_y-1;i++) {
      for(j=0;j<=size_tot_x-1;j++) {
          x0[i][j] = x0_val2[i*j*size_tot_z];
      x[i][j] = x_val2[i*j*size_tot_z];
      }
     }     

你能看到错误在哪里吗?

谢谢

4

3 回答 3

1

你的代码对我来说似乎太复杂了。做就是了:

 double ***x;
 x = malloc(size_tot_y * sizeof(*x));
 for (i = 0; i < size_tot_y; i++) {
   x[i] = malloc(size_tot_x * sizeof(**x));
   for (j = 0; j < size_tot_x; j++) {
     x[i][j] = malloc(size_tot_z * sizeof(***x));
   }
 }

x0. 将其包装在一个例程中,这样您就不需要两次编写相同的代码。

编辑

对于连续数组,请执行以下操作:

 double *storage = malloc(size_tot_x * size_tot_y * size_tot_z * sizeof(*storage));
 double *alloc = storage;
 double ***x;
 x = malloc(size_tot_y * sizeof(*x));
 for (i = 0; i < size_tot_y; i++) {
   x[i] = malloc(size_tot_x * sizeof(**x));
   for (j = 0; j < size_tot_x; j++) {
     x[i][j] = alloc;
     alloc += size_tot_z;
   }
 }

那是如果你真的想要指针。如果没有,只需分配所有内存并自己进行索引:

double *storage = malloc(size_tot_x * size_tot_y * size_tot_z * sizeof(*storage));
double get(const double *storage, int x, int y, int z) {
    return storage[(y * size_tot_x + x) * size_tot_z + z];
}
于 2012-10-04T21:38:47.803 回答
0

我需要 MPI 代码的 3d 连续数组,我在进程之间交换 2d 数组。为此,我使用需要连续数组的 MPI_Sendrecv 例程。

@Keith,您的解决方案似乎不起作用。

例如,在此代码的 2D 版本中,我以x0这种方式创建 2D 连续数组:

  x0 = malloc(size_tot_y*sizeof(double*));
  x0_vals = malloc(size_tot_x*size_tot_y*sizeof(double));

  for(j=0;j<=size_tot_y-1;j++) {
    x0[j] = &x0_vals[j*size_tot_x];
  }

3D 的等价物是什么?

于 2012-10-05T18:20:37.760 回答
0

我大约一年前才开始使用 C,而你对这个人一点帮助也没有。

我还想使用连续的内存块来制作张量,这是奇怪的多维对象。想象一下打印在立方体的 3 个正交面上的三个 3x3 矩阵。

C 中的一个大问题是,当你制作一个 3D 数组时,arr[number][column][row],这将是“column x row”矩阵的“number”,内存块是连续的,但它没有很好的排序.

你有没有想过为什么要初始化一个说 arr[2][4][4] 的数组

int arr[2][4][4]=   
        {
            {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 16}
            },
            {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 16}
            },
        };

但是我们都知道 C 从零开始计数,所以我们将矩阵嵌入到一个更大的矩阵中,周围有垃圾数据,第三个矩阵完全是垃圾数据。这是我打印垃圾数据的方式:

#define COMPLEX 2
#define ROW 2
#define COLUMN 2
void L_print(int u[COMPLEX][ROW][COLUMN])
{
    int i,j,k;
    for(i=0;i<=COMPLEX;i++)
    {
        for(j=0;j<=ROW;j++)
        {
            for(k=0;k<=COLUMN;k++)
            {
                printf("%d ",u[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }
}

所以你得到了嵌入垃圾矩阵的正确数据。C 似乎用随机垃圾数据填充垃圾数据槽,它们并不全是 '\0' 或类似的东西。

所以我想使用指针来修改矩阵大小的运行时,因此我必须基于指针为我的操作做一个同构。

现在,当我声明一个指针并将其指向我的矩阵的第一个条目时:

ptr=&a[0][0][0];

然后我打印

 L_ptr_print(ptr,(2*4*4));  

这将吐出正确的矩阵条目,在这种情况下是两个 4x4 矩阵。

但是我们都知道数组从零开始计数,因此数组 arr[2][4][4] 实际上有 3*5*5 个 sizeof(int) 大的“槽”。所以让我们打印插槽!

L_ptr_print(ptr,(3*5*5));

您将得到的是前 32 个条目是正确排序的矩阵条目。接下来的 43 个条目是完全打印出矩阵 arr[2][4][4] 时得到的垃圾数据。

因此,我已经确定,制作 3D 动态分配的连续数组的最简单和最优雅的方法不是一开始就不让它成为 3D。

只需 malloc 指针并使其大小等于数组元素的数量。所以你会 malloc 一个 32*sizeof(int) 指针:

int* ptr;
ptr=(int*)malloc(32*sizeof(int));

然后像这样填充数组的每个元素,或者你想做什么。

for(i=0;i<31;i++)
{
    *(ptr+i)=i+1;
}

这可以打印出 32 个整数,而且只有 32*sizeof(int) 个字节。这消除了对双指针和三指针的需要。

或者,如果您已经有一个矩阵,您总是可以手动将单个指针指向每个块,然后您不必担心清除内存,因为您的指针不占用内存,数组占用,并且指针指向到数组。但是你不能在运行时修改数组的大小。

于 2016-07-16T21:26:44.860 回答