3

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?

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197
  • you want to remove all the small allocations with just one ? – Raxvan Feb 07 '14 at 12:46
  • @Raxvan Would it be possible? It would be already something – Antonio Feb 07 '14 at 12:47
  • whel yes , but you need to handle the [] operators – Raxvan Feb 07 '14 at 12:48
  • Well, there is no way to get exactly this, that is to have array with lesser overhead than malloced one (for allocation and deallocation) in current C++. If you don't mind the allocation overhead, use `vector` and index like this `[size1*i + j]`. (This should have the same access overhead as VLA in C) – Xarn Feb 07 '14 at 13:04

4 Answers4

2

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])
outis
  • 75,655
  • 22
  • 151
  • 221
0

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'.

TNA
  • 2,595
  • 1
  • 14
  • 19
0

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.

Raxvan
  • 6,257
  • 2
  • 25
  • 46
0

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;