Ниже приведен простой способ создания 3D-массивов с использованием 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, оно называется массивами переменной длины. Вы смотрите here для деталей.
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 делают это хорошо, поэтому нет необходимости изобретать велосипед. Я по-прежнему считаю, что интересно знать, что это легко сделать.
Копать старые кости, я знаю ... но почему люди используют C++, когда «основные» вещи, такие как многомерные массивы, предоставляются бесплатно с другими языками более высокого уровня? Это то, что вам нужно использовать C++, так что ваши руки связаны за спиной? Представление? – MikeMurko 2011-11-19 02:23:38
Hi MikeMurko, в это время разум, связанный руками, был бы самым правильным. Я был бы счастлив сделать что-то подобное на Java или C#. – AndyUK 2011-12-04 16:16:43