C++ Multi-dimensional Arrays on the Heap
Solution 1
If you know the size of nested dimensions already, you can also literally allocate a multi dimensional array using new:
typedef int dimensions[3][4];
dimensions * dim = new dimensions[10];
dim[/* from 0 to 9 */][/* from 0 to 2 */][/* from 0 to 3 */] = 42;
delete [] dim;
instead of 10
, a runtime determined value can be passed. Since it's not part of the type operator new returns, that's allowed. This is nice if you know the number of columns, but want to keep the number of rows variable, for example. The typedef makes it easier to read the code.
Solution 2
See this: C++ FAQ by Marshall Cline
See "How do I allocate multidimensional arrays using new?" and "But the previous FAQ’s code is SOOOO tricky and error prone! Isn’t there a simpler way?" sections.
Solution 3
For the sake of completeness, here is a better way to do it in C++ when you know the array bounds ahead of time. The benefit of using the following class is that you don't have to care about calling delete[] on your data. This means that this class will be exception-safe, and all of the other great stuff about RAII.
template<typename T, int width, int height>
class MultiArray
{
private:
typedef T cols[height];
cols * data;
public:
T& operator() (int x, int y) { return data[x][y]; }
MultiArray() { data = new cols[width]; }
~MultiArray() { delete [] data; }
};
Usage:
MultiArray<int, 10, 10> myArray;
myArray(2, 3) = 4;
cout << myArray(2, 3);
edit: and, while I'm at it, here is the setup you can use if you don't know the array bounds until runtime:
template<typename T>
class Array2D
{
private:
const int width;
T * data;
public:
T& operator() (int x, int y) { return data[y*width + x]; }
Array2D(const int w, const int h) : width(w) { data = new T[w*h]; }
~Array2D() { delete [] data; }
};
Usage:
Array2D myArray(10, 10);
myArray(3, 4) = 42;
cout << myArray(3, 4);
Solution 4
How about using Boost.Multiarray ? I believe it answers your need quite well ! http://www.boost.org/doc/libs/1_37_0/libs/multi_array/doc/user.html#sec_introduction
Here is an excerpt from the documentation page :
#include < boost/multi_array.hpp >
#include < cassert >
int main ()
{
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array< double, 3 > array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
Solution 5
std::vector<std::vector<int> >
should be mentioned, as it's often the simplest way. However, be aware that it is non-rectangular. Not every std::vector<int>
needs to have the same length.
Malice
Updated on July 09, 2022Comments
-
Malice almost 2 years
How would I go about dynamically allocating a multi-dimensional array?