【问题标题】:How do you dynamically allocate a contiguous 3D array in C?如何在 C 中动态分配连续的 3D 数组?
【发布时间】:2010-03-09 19:46:05
【问题描述】:

在 C 中,我想按此顺序循环遍历数组

 for(int z = 0; z < NZ; z++)
    for(int x = 0; x < NX; x++)
       for(int y = 0; y < NY; y++)
           3Darray[x][y][z] = 100;

如何创建这个数组,使 3Darray[0][1][0] 在内存中正好位于 3Darray[0][2][0] 之前?

我可以进行初始化以进行“z-major”排序,但我真的想要这个 3d 数组的 y-major 排序

这是我一直在尝试使用的代码:

char *space;
char ***Arr3D;
int y, z;
ptrdiff_t diff;



space = malloc(X_DIM * Y_DIM * Z_DIM * sizeof(char))

Arr3D = malloc(Z_DIM * sizeof(char **));

for (z = 0; z < Z_DIM; z++)
{
    Arr3D[z] = malloc(Y_DIM * sizeof(char *));

    for (y = 0; y < Y_DIM; y++)
    {
        Arr3D[z][y] = space + (z*(X_DIM * Y_DIM) + y*X_DIM);
    }
}

【问题讨论】:

  • 您是否要分配一个连续的数组?还是尝试更改顺序?
  • 我正在尝试分配一个连续的数组。当我访问它时,我想访问它,以便循环按以下顺序排列:Z -X -Y。这意味着 Y 的增量最快,所以我希望 Y 值在内存中是最连续的
  • 所以基本上你想在 1 个 malloc 语句中分配一个 3D 数组?
  • 正确,并且可以用三括号表示法访问它,其中中间括号是内存中“最连续的”
  • imo,这是不可能的(我可能错了)。即使你用一个 malloc 分配一个 3D 数组(我在大学期间做过),Arr3D[x][y] 也将是一个指向数组的指针。所以 Arr3D[0][1][0] 和 Arr3D[0][2][0] 不会是连续的

标签: c arrays 3d malloc


【解决方案1】:

您无法更改语言中隐含的数组排序。数组排序在 C 中是标准的。

如果您想更改排序方式,只需更改访问数组的方式,即:[x][z][y] 而不是[x][y][z]

【讨论】:

  • 你确定吗?我怀疑是这种情况,但我一直找不到原因。我正在使用 malloc 动态创建数组并使用偏移量。我已经编辑了原始帖子以显示我一直在尝试使用的代码
  • 注意:我已经尝试在该代码中切换一些尺寸,但每次都或多或少地出现相同的顺序
  • @Derek:C always 对多维数组使用行优先排序。 Fortran(和 matlab)使用列优先。这是 C 规范的一部分。见:en.wikipedia.org/wiki/Row-major_order
  • @Reed Copsey,我认为它不会起作用,因为展开三维数组将是 [XYZ][XYZ][XYZ] 并且请求者希望 Y 值是连续的。跨度>
  • 您始终可以将数组访问封装在一个宏中,以便 A(a,x,y,z) 扩展为 a[x][z][y]
【解决方案2】:

我认为这样做的唯一方法是在连续的数据存储上编写自己的风/展开功能。换句话说,您将不得不编写自己的地图来计算值的存储位置。

如果您试图使数组的特定顺序遍历更有效,您总是可以在将传入矩阵 放入数组之前对其进行变换,然后在得到它时再次进行变换出去。 C 风格的多维数组是按顺序排列的,因此数学运算可能会有些棘手(并且超出了我目前所能详细说明的范围)。

很抱歉没有更好的答案,但我希望对您有所帮助

【讨论】:

  • 是的,我实际上是在努力避免这种情况,因为我正在处理一些不是我编写的代码的内存分配问题。重新编写代码以使用该指针算法对于获取代码并希望使用方括号语法的最终用户来说并不完全是一种选择
【解决方案3】:

使用指针数组可以加快速度,但代价是更复杂。如果您不确定是否需要性能,那么您可以尝试使用 C 宏:

#define ARR3D(x,y,z) space[(x) + XDIM*((y) + Y_DIM*(z))]

这假设 x、y 和 z 分别是最内、中间和最外的维度。

【讨论】:

  • 除非我的理解是错误的,否则就是上面示例代码中发布的 arr3d 的情况。我尝试为指针数组中分配的值切换维度,但运气不佳
【解决方案4】:

伪代码:

malloc a chunk of memory big enough for
   the char *** pointer for z,
   the char ** pointers for y, which will get pointed to by zs
   the char * pointers for x, which will get pointed to by ys
   the big block of data that they will, in the end, be pointed to by xs
assign z's, y's, x's so that 
    contiguous blocks from the big block of data are adjacent in the y dimension
    (instead of adjacent in the x dimension, as would be normal)

我已经为 2D 数组完成了单 malloc 技巧,仅仅是因为脑力锻炼和单个 malloc/single free 的额外便利,而且它工作得很好(只要确保获得一个对齐良好的内存块) .我从来没有想过用它来颠覆内存邻接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 2021-12-02
    • 2012-05-01
    • 1970-01-01
    • 2021-02-09
    • 2022-01-14
    相关资源
    最近更新 更多