创建大型的2d数组int arr [1000000] [1000000]

时间:2013-02-03 01:43:32

标签: c++ boost

我想创建一个大小为10 6 ×10 6 元素的二维整数数组。为此,我正在使用boost库:

boost::multi_array<int, 2> x(boost::extents[1000000][1000000]);

但它引发了以下异常:

  

在抛出'std :: bad_alloc'实例后终止调用   what():std :: bad_alloc

请告诉我如何解决问题。

3 个答案:

答案 0 :(得分:5)

你真的不想分配一个巨大的数组。它的内存大约是4TB。

根据您对该阵列的处理方式,您应该考虑两个选项:

  • 外部数据结构。阵列将写在硬盘上。最近访问的部分也在RAM中,因此根据您访问它的方式,它可以非常快,但当然永远不会像在RAM中完全一样快。查看STXXL的外部数据结构。

    此方法的优点是可以访问数组中的所有元素(与您将看到的第二种方法相反)。然而,问题仍然存在:即使在硬盘驱动器上,4TB也非常大,至少如果你在谈论一般的桌面应用程序。

  • 稀疏数据结构。如果您实际上只需要该数组中的一些项目,但是您想要在10⁶⁶10⁶大小的空间内处理这些项目,请不要使用一个数组,但像地图或两者的组合:在“块”中分配数组,比方说1024 x 1024元素。将这些块放入映射中,同时引用块索引(坐标除以1024)作为映射中的键。

    此方法的优点是您不必链接到另一个库,因为它可以由您自己轻松编写。但是,它的缺点是,如果访问分布在整个坐标空间10⁶⁶10⁶或甚至需要所有值的元素,它也会使用大约4TB(甚至更多)的内存。它只适用于您实际只能访问这个巨大的“虚拟”阵列的智能部分。

    以下(未经测试的)C ++代码应该证明这一点:

    class Sparse2DArray
    {
        struct Coord {
            int x, y;
            Coord(int x, int y) : x(x), y(y) {}
            bool operator<(const Coord &o) const { return x < o.x || (x == o.x && y < o,y); }  // required for std::map
        };
    
        static const int BLOCKSIZE = 1024;
    
        std::map<Coord, std::array<std::array<int,BLOCKSIZE>,BLOCKSIZE> blocks;
    
        static Coord block(Coord c) {
            return coord(c.x / BLOCKSIZE, c.y / BLOCKSIZE);
        }
        static Coord blockSubCoord(Coord c) {
            return coord(c.x % BLOCKSIZE, c.y % BLOCKSIZE);
        }
    
    public:
        int & operator[](int x, int y) {
            Coord c(x, y);
            Coord b = block(c);
            Coord s = blockSubCoord(c);
            return blocks[b][s.x][s.y];
        }
    };
    

    您可以使用std::map(哈希映射)代替std::unordered_map,但必须为operator<类型定义哈希函数而不是Coord(或使用std::pair代替。)

答案 1 :(得分:2)

当您以这种方式创建数组时,它将在堆栈上创建,并且堆栈的大小有限。因此,您的程序将崩溃,因为它没有足够的空间来分配那么大的数组。

有两种方法可以解决这个问题,你可以使用new关键字在heap上创建数组但是你必须删除它后面的内容,否则你会有内存泄漏,同时要小心,因为堆具有更大的内存大小,然后堆栈仍然是有限的。

另一种方法是让你在std::vector内使用std::vector并让它为你处理内存。

答案 2 :(得分:0)

您打算创建一个10 6 ×10 6 矩阵?如果你试图创建一个稀疏矩阵(即10个sup <6>有限元的传热问题的扩散矩阵),那么你应该看看使用现有的线性代数库。例如,trilinos项目支持解决大型稀疏矩阵,例如您可能尝试创建的稀疏矩阵。