0

I want to create a two-dimensional integer array of size 106 × 106 elements. For this I'm using the boost library:

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

But it throws the following exception:

terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc

Please tell me how to solve the problem.

4

3 回答 3

5

你真的不想分配一个那么大的数组。它的内存大约为 4 TB。

根据您要对该数组执行的操作,您应该考虑两个选项:

  • 外部数据结构。阵列将被写入硬盘驱动器。最近访问的部分也在 RAM 中,因此取决于您访问它的方式,它可能会非常快,但当然永远不会像完全在 RAM 中那样快。查看STXXL以了解外部数据结构。

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

  • 稀疏数据结构。如果您实际上只需要该数组中的几个项目,但您想在大小为 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您也可以使用(hash map) 而不是a ,std::unordered_map但必须定义一个散列函数而不是类型(或使用)。operator<Coordstd::pair

于 2013-02-03T02:12:51.680 回答
2

When you create an array that way, it is created on the stack and the stack has a limited size. Therefore, your program will crash because it doesn't have enough room to allocate that big of an array.

There are two ways you can solve this, you can create the array on the heap using the new keyword But you have to delete it afterword or else you have a memory leak, and also be careful because while the heap has a larger memory size then the stack it is still finite.

The other way is for you to use std::vector inside std::vector and let it handle the memory for you.

于 2013-02-03T01:47:49.023 回答
0

创建一个 10 6 ×10 6矩阵的目的是什么?如果您正在尝试创建一个稀疏矩阵(即具有 10 6 个有限元的传热问题的扩散矩阵),那么您应该考虑使用现有的线性代数库。例如,trilinos项目支持求解大型稀疏矩阵,例如您可能尝试创建的矩阵。

于 2013-02-03T02:23:01.087 回答