C++ Multi-dimensional Arrays on the Heap

26,538

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.

Share:
26,538
Malice
Author by

Malice

Updated on July 09, 2022

Comments

  • Malice
    Malice almost 2 years

    How would I go about dynamically allocating a multi-dimensional array?