views:

443

answers:

5

Possible Duplicates:
Malloc a 3-Dimensional array in C?
dynamic allocation/deallocation of 2D & 3D arrays

How can i allocate 3D arrays using malloc?

+1  A: 

array = malloc(num_elem * num_elem * num_elem * sizeof(array_elem));

Why not? :)

Roman D
My bad, poor explanation. Of course, there's num_elem_x, num_elem_y and num_elem_z.
Roman D
+1 simpler is better
AareP
@AareP, it's simpler to allocate the memory, but not simpler to use. You can't use the normal [i][j][k] syntax with this.
Peter Alexander
@Poita_, added an answer to this page about this indexing syntax..
AareP
A: 

This would work

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>;
}
Duleb
A: 

There are two different ways to allocate a 3D array. You can allocate it either as a 1D array of pointers to a (1D array of pointers to a 1D array). This can be done as follows:

 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));
          }

        }

Sometimes it is more appropriate to allocate the array as a contiguous chunk. You'll find that many existing libraries might require the array to exist in allocated memory. The disadvantage of this is that if your array is very very big you might not have such a large contiguous chunk available in memory.

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));

To access your array you just use the macro:

ARR(1,0,3) = 4;
Il-Bhima
A: 

For a given type T (non-contiguous):

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);
      }
    }
  }
}

Unless you are working with a very old (pre-C89) implementation, you do not need to cast the result of malloc(), and the practice is discouraged. If you forget to include stdlib.h or otherwise don't have a prototype for malloc() in scope, the compiler will type it to return int, and you'll get an "incompatible type for assignment"-type warning. If you cast the result, the warning is suppressed, and there's no guarantee that a conversion from a pointer to an int to a pointer again will be meaningful.

John Bode
A: 

@Poita_, ok, maybe you are right, but if somebody still wants to use 3-dimensional array allocated in one big chunk, here's how you add normal indexing to it:

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;
}
AareP