What is the good way (understand idiomatic/good practice) to dynamically create a multidimensional array in C++.
For example let say I have tree integers w
, h
and d
and I want to create an array MyEnum my_array[w][h][d]
. (Of course w, h and d are not known at compile time).
Is it best to use nested std::vector or use new or something ?
Bonus question : Is it possible to set the dimension dynamically too ?
In general, nesting
std::vector
is not a great idea. It's usually a better plan to allocate memory which will hold the entirety of your multidimensonal array as a contiguous block, and then index into it as if it were multidimensional. This memory block could be allocated vianew
, but unless you need some precise control over how it's allocated (custom allocator), I'd recommend sticking with a singlestd::vector
.It's not difficult to create a class to manage such a resource in which the number of dimensions can be set dynamically. A good way to organize such a class is to keep track of the allocated memory, the sizes of each dimension, and the stride pattern for each dimension. The strides describe how many elements must be incremented over in order to reach the next element along a given dimension.
This allows efficient indexing (just pointer arithmetic), as well as very efficient reshaping: as long as the number of elements doesn't change, this just requires changing the shape and stride arrays.
Example:
Here's a very basic class which will store such a dynamical multidimensional array of
double
s. It stores data in row-major order, meaning that the last index varies the fastest. So for a 2D array, the first row is stored contiguously, followed by the second row, and so on.You can reshape the array, changing the number of dimensions, if you want. A basic element access
operator[]
is shown, too. There's nothing else fancy about the class, but you can extend it to provide whatever functionality you want, e.g., iterators, mathematical operations on the data, I/O operators, etc.Here's a basic demo of the functionality.
You can compile the test program with
g++ -std=c++14 -o test test.cc
, assuming the file defining the class is in the same directory astest.cc
.