user974967
user974967

Reputation: 2946

dynamically allocating 3d array

I'm a little confused about dynamically allocating a 3d array. Right now, I'm just allocating one big block of memory like so:

int height = 10;
int depth = 20;
int width = 5;

int* arr;
arr = new int[height * width * depth];

Now I'd like to change a value in the 3D array, say:

//arr[depth][width][height]
arr[6][3][7] = 4;

However, I can't use the above code to change the value. How can I use a single index to access the element at position depth = 6, width = 3, height = 7?

arr[?] = 4;

Is there a better way to dynamically allocate a 3D array?

Upvotes: 7

Views: 34641

Answers (4)

Sagar Patnaik
Sagar Patnaik

Reputation: 51

Allocation and deallocation for a 3D array (in heap) are exactly the opposite to each other. The key thing to remember, while deallocating the memory properly, is to use the delete keywords as many times as the new keyword has been used. Here's my code for initialization and clean up of a 3D array:

int ***ptr3D=NULL;
ptr3D=new int**[5];

for(int i=0;i<5;i++)
{
    ptr3D[i] = new int*[5];  

    for(int j=0;j<5;j++)
    {
        ptr3D[i][j]=new int[5]; 

        for(int k=0;k<5;k++)
        {
            ptr3D[i][j][k]=i+j+k; 
        }
    }
}
//Initialization ends here
...
... //Allocation of values

cout << endl <<"Clean up starts here " << endl;

for(int i=0;i<5;i++)
{
    for(int j=0;j<5;j++)
    {
        delete[] ptr3D[i][j];   
    }
    delete[] ptr3D[i];
}
delete ptr3D;

Notice that for 3 new keywords, 3 corresponding delete keywords have been used. This should clean up all the memory allocated to the 3D array in heap and Valgrind can be used to verify it in each stage.

Upvotes: 5

AarCee
AarCee

Reputation: 863

To have a simple indexing mechanism like arr[height][width][depth], and to also have default values in the allocated memory to be initialized to 0, please try the following:

// Dynamically allocate a 3D array
/*  Note the parenthesis at end of new. These cause the allocated memory's
    value to be set to zero a la calloc (value-initialize). */
    arr = new int **[height]();
    for (i = 0; i < height; i++)
    {
        arr[i] = new int *[width]();
        for (j = 0; j < width; j++)
            arr[i][j] = new int [depth]();
    }

And here's the corresponding deallocation:

//Dynamically deallocate a 3D array

for (i = 0; i < rows; i++)
{
    for (j = 0; j < columns; j++)
        delete[] arr[i][j];
    delete[] arr[i];
}
delete[] arr;

Upvotes: 7

Jesse Good
Jesse Good

Reputation: 52355

To index into the flat 3-dimensional array:

arr[x + width * (y + depth * z)]

Where x, y and z correspond to the first, second and third dimensions respectively and width and depth are the width and depth of the array.

This is a simplification of x + y * WIDTH + z * WIDTH * DEPTH.

Upvotes: 11

yaman
yaman

Reputation: 769

C inclined way of doing this is:

int ***arr = new int**[X];
for (i = 0; i < z_size; ++i) {
  arr[i] = new int*[Y];
  for (j = 0; j < WIDTH; ++j)
    arr[i][j] = new int[Z];
}

Upvotes: 16

Related Questions