6

我对动态分配 3d 数组有点困惑。现在,我只是像这样分配一大块内存:

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

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

现在我想改变 3D 数组中的一个值,比如:

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

但是,我不能使用上面的代码来更改值。如何使用单个索引访问位置深度 = 6、宽度 = 3、高度 = 7 的元素?

arr[?] = 4;

有没有更好的方法来动态分配 3D 数组?

4

4 回答 4

15

C 倾向于这样做的方式是:

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];
}
于 2012-04-20T00:38:41.097 回答
10

要索引到平面 3 维数组:

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

其中 x、y 和 z 分别对应第一维、第二维和第三维,宽度和深度是阵列的宽度和深度。

这是 的简化x + y * WIDTH + z * WIDTH * DEPTH

于 2012-04-20T00:49:07.180 回答
7

要拥有像 arr[height][width][depth] 这样的简单索引机制,并且还要在分配的内存中将默认值初始化为 0,请尝试以下操作:

// 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]();
    }

这是相应的释放:

//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;
于 2015-05-17T06:57:14.803 回答
5

3D 数组(在堆中)的分配和解除分配是完全相反的。要记住的关键是,在正确释放内存的同时,使用关键字的次数与使用delete关键字的次数一样多new。这是我用于初始化和清理 3D 数组的代码:

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;

请注意,对于 3 个new关键字,使用了 3 个相应的delete关键字。这应该清理堆中分配给 3D 数组的所有内存,并且 Valgrind 可用于在每个阶段对其进行验证。

于 2017-03-22T12:42:22.170 回答