Question

Let's say I have a multidimension array, which in C99 I could write like this:

#define SIZE1 10
int size2;

[...]

int myArray[SIZE1][size2];

Although supported by several compilers, this is not strictly C++, and won't be included until C++14. To obtain the same (apart stack/heap problem irrelevant for my case) using boost::scoped_array, I write:

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

So, not so concise expression. Am I missing something, or for multidimension arrays with variable length there is no easy plain C++ way to obtain a quick allocation?

Some reference: Why aren't variable-length arrays part of the C++ standard?

Was it helpful?

Solution

std::vector will take both a size and an initial value, which you can use to set initial size of both the outer and inner vector:

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

boost::multi_array is specifically designed as a multidimensional array, and is more fitting than boost::scoped_array.

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

OTHER TIPS

There is no multidimensional arrays with variable length in the C++ standard but you can easily write you own matrix class with an vector in it that calculates the vector Index by 'row_index*rowlength + column_index'.

If all you need is a multidimensional array you could use pointers, resizing would require copying onto a new one and deleting the old, but you could do the following:

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;   

or as an alternative you could use a pointer to a 1D array such as:

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

and access it by:

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

providing a delete statement:

delete [] m;   

There is no default container for this, you need to write one if you want only one allocation. This is the shortest example i can give:

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;

Notice that the elements are allocated all in one vector and to find an element at x and y i used y * width + x to obtain the index in the vector.

Also there are already implementations for this purpose so it would be best to take one from the internet. You can check boost library for what they have there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top