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?

4
  • you want to remove all the small allocations with just one ? Commented Feb 7, 2014 at 12:46
  • @Raxvan Would it be possible? It would be already something Commented Feb 7, 2014 at 12:47
  • whel yes , but you need to handle the [] operators Commented Feb 7, 2014 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<int> and index like this [size1*i + j]. (This should have the same access overhead as VLA in C) Commented Feb 7, 2014 at 13:04

4 Answers 4

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])
Sign up to request clarification or add additional context in comments.

1 Comment

boost::multi_array and boost::extents, that does it, thank you!!
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'.

Comments

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;   

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.