Ниже приведен простой способ создания трехмерных массивов с использованием C или C ++ в одном фрагменте памяти для каждого массива. Нет необходимости использовать BOOST (даже если это хорошо) или разделять распределение между строками с множественной косвенностью (это очень плохо, поскольку обычно дает большой выигрыш в производительности при доступе к данным и фрагментирует память).
Единственное, что нужно понять, - это то, что нет многомерных массивов, а есть только массивы (массивов). Самый внутренний индекс самый дальний в памяти.
#include <stdio.h>
#include <stdlib.h>
int main(){
{
// C Style Static 3D Arrays
int a[10][20][30];
a[9][19][29] = 10;
printf("a[9][19][29]=%d\n", a[9][19][29]);
}
{
// C Style dynamic 3D Arrays
int (*a)[20][30];
a = (int (*)[20][30])malloc(10*20*30*sizeof(int));
a[9][19][29] = 10;
printf("a[9][19][29]=%d\n", a[9][19][29]);
free(a);
}
{
// C++ Style dynamic 3D Arrays
int (*a)[20][30];
a = new int[10][20][30];
a[9][19][29] = 10;
printf("a[9][19][29]=%d\n", a[9][19][29]);
delete [] a;
}
}
Для вашей реальной проблемы, поскольку потенциально есть два неизвестных измерения, есть проблема с моим предложением: разрешить только одно неизвестное измерение. Есть несколько способов справиться с этим.
Хорошей новостью является то, что использование переменных теперь работает с C, это называется массивами переменной длины. Вы смотрите здесь для деталей.
int x = 100;
int y = 200;
int z = 30;
{
// C Style Static 3D Arrays
int a[x][y][z];
a[99][199][29] = 10;
printf("a[99][199][29]=%d\n", a[99][199][29]);
}
{
// C Style dynamic 3D Arrays
int (*a)[y][z];
a = (int (*)[y][z])malloc(x*y*z*sizeof(int));
a[99][199][29] = 10;
printf("a[99][199][29]=%d\n", a[99][199][29]);
free(a);
}
Если вы используете C ++, возможно, проще всего использовать перегрузку операторов, чтобы придерживаться синтаксиса массива:
{
class ThreeDArray {
class InnerTwoDArray {
int * data;
size_t y;
size_t z;
public:
InnerTwoDArray(int * data, size_t y, size_t z)
: data(data), y(y), z(z) {}
public:
int * operator [](size_t y){ return data + y*z; }
};
int * data;
size_t x;
size_t y;
size_t z;
public:
ThreeDArray(size_t x, size_t y, size_t z) : x(x), y(y), z(z) {
data = (int*)malloc(x*y*z*sizeof data);
}
~ThreeDArray(){ free(data); }
InnerTwoDArray operator [](size_t x){
return InnerTwoDArray(data + x*y*z, y, z);
}
};
ThreeDArray a(x, y, z);
a[99][199][29] = 10;
printf("a[99][199][29]=%d\n", a[99][199][29]);
}
Приведенный выше код имеет некоторую косвенную стоимость для доступа к InnerTwoDArray (но, вероятно, хороший компилятор может его оптимизировать), но использует только один кусок памяти для массива, выделенного в куче. Что обычно является наиболее эффективным выбором.
Очевидно, что даже если приведенный выше код все еще прост и понятен, STL или BOOST делают это хорошо, поэтому нет необходимости заново изобретать колесо. Я все еще верю, что интересно знать, что это легко сделать.