在C ++中为多维数组分配,部分是可变长度的

时间:2014-02-07 12:41:52

标签: c++ variable-length-array

假设我有一个多维数组,在C99中我可以像这样编写:

#define SIZE1 10
int size2;

[...]

int myArray[SIZE1][size2];

虽然有几个编译器支持,但这不是严格的C ++,直到C ++ 14才会包含。 为了获得相同的(与我的情况无关的堆栈/堆问题)使用boost :: scoped_array,我写道:

boost::scoped_array<int> myArray[SIZE1];
for (int i = 0; i < SIZE1; i++)
    myArray[i].reset(new int[size2]);

所以,没有那么简洁的表达。 我错过了什么,或者对于长度可变的多维数组,没有简单的C ++方法来获得快速分配?

一些参考:Why aren't variable-length arrays part of the C++ standard?

4 个答案:

答案 0 :(得分:2)

std::vector将获取大小和初始值,您可以使用它来设置外部和内部向量的初始大小:

vector< vector<int> > myArray(SIZE1, vector<int>(size2));

boost::multi_array专门设计为多维数组,比boost::scoped_array更合适。

boost::multi_array<int, 2> myArray(boost::extents[SIZE1][size2])

答案 1 :(得分:0)

在C ++标准中没有可变长度的多维数组,但您可以轻松编写自己的矩阵类,其中包含一个向量,通过'row_index * rowlength + column_index'计算向量索引。

答案 2 :(得分:0)

没有默认容器,如果只需要一次分配,则需要编写一个。这是我能给出的最短的例子:

template <class T>
class Matrix
{
public:
    Matrix(const unsigned int _width,const unsigned int _height)
        :width(_width)
        ,height(_height)
    {
        elements.resize(width * height);//one allocation !
    }
    //x goes on width
    //y on height
    T&              get(const unsigned int x,const unsigned int y)
    {
        return elements[y * width + x];
    }
public:
    unsigned int    width;
    unsigned int    height;
    std::vector<T>  elements;
};

//usage:
Matrix<int> m(width_size,height_size);
m.get(10,10) = element;

请注意,元素在一个向量中分配,并在xy找到一个元素,我使用y * width + x来获取向量中的索引。

此外,已有针对此目的的实施,因此最好从互联网上取一个。您可以查看boost library他们在那里的内容。

答案 3 :(得分:0)

如果您需要的是一个多维数组,您可以使用指针,调整大小需要复制到新的并删除旧的,但您可以执行以下操作:

int** m;
int rows, cols;
cin >> rows >> cols;
m = new int* [rows];
for (int i = 0; i < rows; i++) {
    m[i] = new int [cols];
}

for (int i = 0; i < rows; i++) {
    delete [] m[i];
}
delete [] m;   

或者作为替代方案,您可以使用指向1D数组的指针,例如:

int* m;
int rows, cols;
cin >> rows >> cols;
m = new int [rows*cols];

并通过以下方式访问它:

for (int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++)
        m[i*cols+j] = i;

提供删除声明:

delete [] m;