Как манипулировать динамическим многомерным массивом в C - PullRequest
1 голос
/ 21 мая 2011

Мне нужно выделить большой многомерный массив как char a[x][32][y], а x * 32 * y составляет около 6 ~ 12G. (x, y определяются во время выполнения.)

Я придумываю способ сделать char *a=malloc(x*32*y) и использовать *(a+32*y*i+y*j+k) для a[i][j][k].

Однако это выглядит не так удобно по сравнению с a[i][j][k].

Есть ли лучший способ?

Добавлено: Это a[x][32][datlen], где datlen определяется во время выполнения, а x устанавливается с учетом памяти.

Все данные в массиве будут новыми. И у меня есть математики с 16 или 32 ГБ памяти для его запуска.

Ответы [ 3 ]

4 голосов
/ 21 мая 2011

НЕПРАВИЛЬНО: Вы по-прежнему сможете использовать синтаксис [i] [j] [k] при обращении к динамически выделяемой памяти.

ПРАВИЛЬНО: использовать макрос, чтобы хотя бы упростить работу

#define A(i,j,k) *(a+32*y*i+y*j+k)
A(1,2,3) would then do the right thing.
1 голос
/ 21 мая 2011

Я сомневаюсь, что вы найдете систему, которая будет выделять вам непрерывную память такого большого размера *.Вам нужно будет использовать какую-то стратегию разбиения на фрагменты.

Вам нужно спросить: «Какова ваша схема доступа к данным?»

Если это какой-то шаг (будь то 1Dили 2D), используйте это, чтобы выбрать соответствующее распределение памяти для каждого блока.Используйте структуру данных для представления каждого шага (это может быть просто структура, содержащая ваши массивы символов).

Редактировать: Я не заметил ваш второй «вопрос» о доступе к вашему недавно найденному 12Gнепрерывный кусок памяти с использованием синтаксиса a[i][j][k].Этого не произойдет ни в одном из известных мне потребительских дистрибутивов класса C.

(*) и 640k должно хватить для всех.

0 голосов
/ 21 мая 2011

Поскольку это C, вы не можете обернуть все в удобный объект C ++.

Но я бы сделал нечто подобное. Разработайте ряд функций, которые будут распределять, манипулировать и уничтожать ваш новый тип данных.

Чтобы прочитать или записать часть данных, вызовите функцию. Никогда не трогайте данные напрямую. На самом деле, если вы можете использовать дескриптор void* для своих данных и даже не помещать реальные типы данных во включенный заголовочный файл, это лучшее, что нужно сделать.

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

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

Я признаю, что matrix_set(x, y, z, value) не так хорош, как matrix[x][y][z] = value, но он будет работать так же хорошо.

...