Как вы динамически выделяете непрерывный трехмерный массив в C? - PullRequest
1 голос
/ 09 марта 2010

В 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", но я действительно хочу упорядочение по y-мажору для этого 3d-массива

Это код, который я пытался использовать:

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

Ответы [ 4 ]

5 голосов
/ 09 марта 2010

Вы не можете изменить порядок массива, неявный в языке. Порядок массива является стандартным в C.

Если вы хотите изменить способ упорядочения, просто измените способ доступа к массиву, например: [x][z][y] вместо [x][y][z].

1 голос
/ 09 марта 2010

Использование массива указателей может ускорить процесс, но за счет большей сложности. Если вы не уверены, что вам нужна производительность, вы можете попробовать использовать макрос C:

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

Это предполагает, что x, y и z являются внутренним, средним и самым внешним измерениями соответственно.

1 голос
/ 09 марта 2010

Я думаю, что единственный способ сделать это - написать свою собственную функцию ветра / раскрутки в непрерывном хранилище данных. Другими словами, вам придется написать свою собственную карту, чтобы рассчитать позицию хранения ваших значений.

Если вы пытаетесь сделать определенный обход вашего массива более эффективным, вы всегда можете преобразовать входящую матрицу до того, как поместите ее в массив, а затем снова выполните преобразование, когда вы получите его , Многомерные массивы в стиле C упорядочены по порядку, так что математика может быть немного хитрой (и это выходит за рамки того, что я могу подробно описать здесь за то время, что у меня есть).

Извините за отсутствие лучшего ответа, но я надеюсь, что это поможет

0 голосов
/ 09 апреля 2010

псевдокод:

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)

Я сделал трюк с одним malloc для двумерных массивов, просто из-за умственных упражнений и дополнительного удобства одиночного освобождения malloc / single, и он прекрасно работает (просто убедитесь, что у вас хорошо выровненный фрагмент памяти) , Я никогда не думал об использовании этого, чтобы разрушить смежность памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...