以下是使用 C 或 C++ 在每个数组的一块内存中创建 3D 数组的简单方法。不需要使用 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 也做得很好,因此无需重新发明轮子。我仍然相信知道它可以很容易地完成是很有趣的。