在C中使用3d连续数组的问题

时间:2012-10-04 21:19:10

标签: c arrays multidimensional-array malloc

我需要在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];
      }
     }     

你能看到错误在哪里吗?

由于

3 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分:0)

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

@Keith,您的解决方案似乎无法运作。

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

  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的等价物是什么?

答案 2 :(得分:0)

我差不多一年前刚开始做C而且你一点都不帮这个人。

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

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

你有没有想过为什么要初始化一组说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似乎用随机垃圾数据填充垃圾数据槽,它们不是全部&#39; \ 0&#39;或类似的东西。

所以我想使用指针来修改矩阵大小的运行时,因此我必须根据指针对我的操作进行同构。

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

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

然后我打印

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

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

但是我们都知道数组从零开始计数,所以数组arr [2] [4] [4]实际上有3 * 5 * 5&#34;插槽&#34;这是sizeof(int)big。所以,让我们打印插槽!

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

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

因此,我已经确定,制作3D动态分配连续数组的最简单,最优雅的方法并非首先使其成为3D。

简单地指向你的指针并使其大小等于数组元素的数量。所以你要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)个字节。这消除了对双指针和三指针的需要。

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