动态分配3D数组

7

我有些困惑于动态分配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;

有没有更好的方法动态分配一个三维数组?

我认为这是指针,如果你需要三个维度,那么应该是 int ***arr = new int[height][width][depth];。 - Russ Clarke
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];
}

11

访问这个平面三维数组的方法是:

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

x、y 和 z 分别对应于第一、第二和第三维,而 width 和 depth 是数组的宽度和深度。

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


抱歉,所以x对应宽度元素,y对应高度元素,z对应深度元素,还是我错了?因此,要获取深度=6,宽度=3,高度=7的元素:arr[3 + 5 * (7 + 20 * 6)] = arr[638]。 - user974967
@user974967:x 是高度,y 是宽度,z 是深度。要访问 arr[6][3][7],请使用 arr[6 + 5 * (3 + 20 * 7)]。基本上是按照高度、宽度、深度的顺序。 - Jesse Good

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;

5

在堆中分配和释放三维数组的方式是完全相反的。在正确释放内存时需要记住的关键事项是使用与new关键字使用的次数相同的delete关键字。

以下是初始化和清理三维数组的代码示例:

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进行验证。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接