不指定数组大小声明多维数组

7

我想声明一个二维数组或多维数组,但不知道其大小。

我想做的类似于我在简单数组中所做的:

int *array;
cin >> size;
array = new int[size];

也许我可以像这样循环初始化指向指针的指针:
int **array;
cin >> rows >> col;
array = new *int[rows]
for (int i = 0; i < rows; ++i)
    array[i] = new int[col];

但是如果有更好的解决方案,我宁愿不这样做。


如果您想要一个大小仅在运行时已知的数组,那么您真正需要的是一个std::vector - cHao
2
你学过标准库吗?你知道什么是std::vector吗? - amdn
@PuraVida,我非常了解标准库,谢谢。我正在测试使用vector<vector<int>>和int[][]数组的性能,所以我需要使用数组,因此我不想使用循环来初始化它。 - blackløtus
4个回答

6
为什么不使用std::vector?
std::vector<std::vector<int> > array;

如果您不想使用指针数组,那么您可以使用一个大型数组。您可以在获取大小后动态分配该数组,并将其作为行数组访问。

int rows = 10;
int columns = 20;

int* array = new int[rows * columns];

for (int count = 0; count < rows; count++)
{
   int* row = &array[count * columns];

   for (int inner_count = 0; inner_count < columns; inner_count++)
   {
      int* element = &row[inner_count];

      //do something
   }
}

delete [] array;

2
如果代码对性能敏感,不要使用“向量的向量”。与单个大块内存相比,您将面临大量缓存未命中。 - Ed S.
@EdS.yea 这是其中一个原因,我想尝试不使用循环来初始化它。 - blackløtus

2

你基本上必须使用循环版本。你可以进行一些小的改进,比如分配一个大块并构建自己的int*索引:

int **array;
int *storage;
cin >> rows >> col;
array = new *int[rows];
storage = new int[rows*col];
for (int i = 0; i < rows; ++i)
    array[i] = storage + col * i;

这种方法的好处是,您仍然可以使用array[i][j]语法来访问数组。

1

您可以使用单个std::vector来包含整个二维数组,并将其封装在一个类中以隐藏细节。这里是一个例子,它使用一个data(row, col)成员函数,返回rowcol位置的元素的引用。我包括了一个int的二维矩阵示例,其中数组中的每个条目都初始化为其rowcol的乘积。当此类的实例超出范围时,默认析构函数将被调用并释放内存,这样您就不必记得调用delete[]来释放内存。矩阵的所有元素都将在内存中连续,这是缓存友好的,应该能够提供良好的性能。

#include <iostream>
#include <vector>
#include <stdexcept>

template <typename T>
class matrix {
    std::vector<T> data_;
public:
    size_t const rows_;
    size_t const cols_;
    matrix(size_t rows, size_t cols)
        : rows_(rows)
        , cols_(cols)
        , data_( rows * cols )
    {}
    T& data( size_t row, size_t col ) {
        if (row > rows_ || col > cols_) throw std::out_of_range("matrix");
        return data_[ row * cols_ + col ];
    }
};

int main( int argc, char** argv )
{
    matrix<int> array(100,100);

    for(size_t r=0; r < array.rows_; ++r) {
        for(size_t c=0; c < array.cols_; ++c) {
            array.data(r,c) = r * c;
        }
    }

    std::cout << "8 x 7 = " << array.data(8,7) << std::endl;

    return 0; // array goes out of scope here, memory released automatically
}

当您运行此程序时,您将获得以下结果

8 x 7 = 56

0

如果你在意的话,你可以通过使用助手来获得更多的便利。

template <typename T>
struct C3DArray
{
    vector<vector<vector<T>>> m;
    C3DArray(int size_x, int size_y, int size_z)
        : m(make(T(), size_z, size_y, size_x))
    { }

    template <typename U> static std::vector<U> make(U v, size_t n) {
        return { n, std::move(v) };
    }

    template <typename U, typename... Dim> static auto make(U v, size_t n, Dim... other)
        -> std::vector<decltype(make(v, other...))> {
        return { n, make(v, other...) };
    }
};

这里使用了可变参数。使用方法如下:

C3DArray<int> arr(3,4,20);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接