【问题标题】:Dynamic memory allocation for 3D array [duplicate]3D数组的动态内存分配[重复]
【发布时间】:2011-01-27 03:28:52
【问题描述】:

可能的重复:
Malloc a 3-Dimensional array in C?
dynamic allocation/deallocation of 2D & 3D arrays

如何使用 malloc 分配 3D 数组?

【问题讨论】:

标签: c memory-management malloc multidimensional-array


【解决方案1】:

有两种不同的方式来分配一个 3D 数组。您可以将其分配为指向一维数组的一维指针数组(指向一维数组的一维指针数组)。这可以按如下方式完成:

 int dim1, dim2, dim3;
 int i,j,k;
 double *** array = (double ***)malloc(dim1*sizeof(double**));

        for (i = 0; i< dim1; i++) {

         array[i] = (double **) malloc(dim2*sizeof(double *));

          for (j = 0; j < dim2; j++) {

              array[i][j] = (double *)malloc(dim3*sizeof(double));
          }

        }

有时将数组分配为连续块更合适。您会发现许多现有库可能要求数组存在于分配的内存中。这样做的缺点是,如果您的数组非常大,您可能在内存中没有这么大的连续块可用。

const int dim1, dim2, dim3;  /* Global variables, dimension*/

#define ARR(i,j,k) (array[dim2*dim3*i + dim3*j + k])
double * array = (double *)malloc(dim1*dim2*dim3*sizeof(double));

要访问您的数组,您只需使用宏:

ARR(1,0,3) = 4;

【讨论】:

  • 1) 不要将void * 转换为 malloc 和 C 中的朋友返回的。2) double *** 等不是 3D 数组,不能作为一个数组使用!它只是碰巧在索引条目时使用与 3D 数组相同的语法,但具有非常不同的语义,因为复杂的嵌套分配已经显示。
【解决方案2】:

这样就可以了

int main()
{

    int ***p,i,j;

    p=(int ***) malloc(MAXX * sizeof(int **));

    for(i=0;i<MAXX;i++)
    {
        p[i]=(int **)malloc(MAXY * sizeof(int *));
        for(j=0;j<MAXY;j++)
            p[i][j]=(int *)malloc(MAXZ * sizeof(int));
    }

    for(k=0;k<MAXZ;k++)
        for(i=0;i<MAXX;i++)
            for(j=0;j<MAXY;j++)
                p[i][j][k]=<something>;
}

【讨论】:

  • 1) 不要将void * 转换为malloc 和C 中的朋友返回的那样。2) double *** 等不是3D 数组,不能作为一个数组使用!它只是碰巧在索引条目时使用与 3D 数组相同的语法,但具有非常不同的语义,因为复杂的嵌套分配已经显示。
【解决方案3】:
array = malloc(num_elem * num_elem * num_elem * sizeof(array_elem));

为什么不呢? :)

【讨论】:

  • 我的错误,糟糕的解释。当然,还有 num_elem_x、num_elem_y 和 num_elem_z。
  • @AareP,分配内存更简单,但使用起来并不简单。你不能使用正常的 [i][j][k] 语法。
  • @Poita_,在此页面上添加了有关此索引语法的答案..
【解决方案4】:

@Poita_,好吧,也许你是对的,但如果有人仍然想使用分配在一大块中的 3 维数组,那么你可以向它添加普通索引:

void*** newarray(int icount, int jcount, int kcount, int type_size)
{
    void*** iret = (void***)malloc(icount*sizeof(void***)+icount*jcount*sizeof(void**)+icount*jcount*kcount*type_size);
    void** jret = (void**)(iret+icount);
    char* kret = (char*)(jret+icount*jcount);
    for(int i=0;i<icount;i++)
        iret[i] = &jret[i*jcount];
    for(int i=0;i<icount;i++)
        for(int j=0;j<jcount;i++)
            jret[i*jcount+j] = &kret[i*jcount*kcount*type_size+j*kcount*type_size];
    return iret;
}

【讨论】:

  • 1) 不要将void * 转换为malloc 和C 中的朋友返回的那样。2) double *** 等不是3D 数组,不能作为一个数组使用!它只是碰巧在索引条目时使用与 3D 数组相同的语法,但具有非常不同的语义,因为复杂的嵌套分配已经显示。
【解决方案5】:

对于给定的类型 T(非连续):

size_t dim0, dim1, dim2;
...
T ***arr = malloc(sizeof *arr * dim0); //type of *arr is T **
if (arr)
{
  size_t i;
  for (i = 0; i < dim0; i++)
  {
    arr[i] = malloc(sizeof *arr[i] * dim1); // type of *arr[i] is T *
    if (arr[i])
    {
      size_t j;
      for (j = 0; j < dim1; j++)
      {
        arr[i][j] = malloc(sizeof *arr[i][j] * dim2);
      }
    }
  }
}

除非您使用的是非常旧的(C89 之前的)实现,否则您不需要转换 malloc() 的结果,并且不鼓励这种做法。如果您忘记包含 stdlib.h 或在范围内没有 malloc() 的原型,编译器将键入它以返回 int,并且您将收到“不兼容的赋值类型”类型警告。如果您转换结果,警告将被抑制,并且不能保证从指向 int 的指针再次转换为指针是有意义的。

【讨论】:

  • double ***等不是3D数组,不能当做一个!它只是碰巧在索引条目时使用与 3D 数组相同的语法,但具有非常不同的语义,因为复杂的嵌套分配已经显示。
猜你喜欢
  • 2018-09-06
  • 2012-05-01
  • 2012-10-09
  • 1970-01-01
  • 2020-10-23
  • 2020-08-07
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
相关资源
最近更新 更多