3D数组c++太大?如何使用3D阵列

3D array c++ too large? how use 3D arrays?

本文关键字:3D 何使用 阵列 太大 数组 c++      更新时间:2023-10-16

我用这种方式创建了一个3D数组:

#define P 1000 int 
SPACE3D[P*2][P*2][P*2];

但是我得到以下编译错误:

错误1错误C2148:数组的总大小不能超过0x7fffffff字节

我能做些什么来避免这个错误吗?

我也尝试像这样初始化3D数组:

int SPACE3D[P*2][P*2][P*2]={0};

这样我就没有编译错误,但是程序崩溃了。

有什么建议吗?

您需要在堆上创建数组,使用newmalloc(),而不是像您那样在堆栈上创建数组。例如:

int* SPACE3D = new int[P*2*P*2*P*2];

现在您需要使用算术索引到它。如果您喜欢更自然、更安全的接口,那么在标准库之外有很多矩阵类可用。但是,请不要使用向量的向量的向量的向量,因为如果您的矩阵实际上是矩形的(即不是锯齿状/稀疏),那么这是非常低效的。

让我们从非技术的角度来解决这个问题:当你将数组命名为"space"时,我假设你想要描述空间。一大堆虚无和一些行星。也许有几艘宇宙飞船。让它成为许多行星和许多宇宙飞船。在10个星球上,每个星球上有10艘飞船,我们有110个单位。

在数组中,描述1000x1000x1000个单位。大多数都是空的。什么都没有。

在现实生活中,你也不会那样做。如果有人问你你所在城市的大象在哪里,你可能会说"动物园里有4头大象"。你不会说"我的房间没有人,隔壁房间没有人,再后面的房间没有人,我上面的房间没有人,我上面的房间没有人,厨房里没有人,街上也没有人…"

你提到大象在哪里,这意味着其他地方没有大象。否则的话,将是对时间和纸张的巨大浪费。

在你的程序中就是这样做的。列出存在的东西。如果你在[1,56,784]处的现有事物列表中没有任何东西,那么这就意味着什么都没有。这样,只要你有一个现有宇宙飞船的列表,你的宇宙就没有限制。连1000x1000x1000都没有

应该在堆上分配大块内存,而不是堆栈:

int array[2*P][2*P][2*P]; // placed on the stack
int* array = new int[8*P*P*P]; // placed on the heap
vector<int> array(8*P*P*P); // vector uses heap storage

在堆栈上,你基本上被限制为几兆字节的内存,而在堆上,你有一个很好的计算机RAM(例如几个GB)可用。

请记住:一个1000*1000*1000 int的3D数组需要4gb的内存!

另外,我建议为你的3D数组建立一个小类:

template<typename K>
class Array3D
{
public:
    Array3D(int size) // beware, data is not initialized!
    : size_(size), data_(size*size*size) {}
    int size() { return size_; }
    size_t index(int x, int y, int z) const {
        return x + size_*(y + size_*z);
    }
    K& operator(int x, int y, int z) {
        return data_[index(x,y,z)];
    }
private:
    size_t size_;
    vector<K> data_;
};

你可以这样使用:

Array3D arr(1000);
arr(12,43,745) = 15;

这个片段缺少很多有用的功能,但它展示了如何构建3D数组的基本原则。要么在类似的基础上构建,要么使用现有的一个库。

在我看来,在c++中,我总是会为数组(1D, 2D,…)使用数据类型来存储数组内存和数组大小,并至少提供某种边界信息。

用这种方式分配3d数组,它看起来太大了。

要查看如何在堆上分配它,请参阅以下答案:堆上的c++多维数组

具体来说,在你的情况下:

#define P 1000
typedef int SPACE2D_t[P*2][P*2];
SPACE2D_t* SPACE3D = new SPACE2D_t[P*2];
SPACE3D[/* from 0 to P*2-1 */][/* from 0 to P*2-1 */][/* from 0 to P*2-1 */] = 42;
delete [] SPACE3D;