Accessing elements in 2D dynamically allocated array? (C++)

Started by
7 comments, last by VitaminCpp 16 years, 9 months ago
Hi guys, is there anyway I can allocate a 2D array dynamically with 'new' and then access elements using the normal [] operator? Some code which doesn't work:

int* myArray = new int[10][20];
myArray[2][3] = 100;

One approach is to declare like this:

int* myArray = new int[10*20];

But then it is only a 1D array. Or I could say something like:

int** myArray = new int*[10];
for(int x = 0; x < 10; x++)
{
    myArray[x] = new int[20];
}

Which then allows the correct syntax for access but means the array could be spread out in memory (bad for cache, can't clear with one call to memset(), etc). Am I missing something obvious? Thanks!
Advertisement
boost::multi_array
I think the easiest solution is to create an Array2D class that stores a 1D array internally and overload the [] operator (and maybe the () operator for 2D access).
Unfortunately, C++ does not support the direct dynamic allocation of true 2D arrays. Arrays in C++ are not first class types. In addition to the approach you've tried, you may want to use:
class MyArray {  public:    int data[10][20];};MyArray * ptr = new MyArray;

Here is another thread on the topic.
Quote:Am I missing something obvious?


Yes:
std::vector< std::vector< int > > myArray;


Quote:Which then allows the correct syntax for access but means the array could be spread out in memory (bad for cache, can't clear with one call to memset(), etc).


If you need fully continuous block of memory:
template < class T >class Array {  Array( size_t w, size_t h )     : m_array( w * h )    , m_width(w)    , m_height(h)  { }  inline T get( size_t x, size_t y ) {    return m_array[ y * m_width + x ];  }  void clear( T defaultValue ) {    std::fill( m_array.begin(), m_array.end(),  defaultValue );  }private:  std::vector< T > m_array;  size_t m_width;  size_t m_height;};
Of the choices you presented, the 2nd approach is probably best...even a 2d array like, say, video memory is represented in 1 dimension.
The 3rd approach will work fine if you need a 2d array...but an array with any number of dimensions is usually best mapped in 1 dimension and accessed with multiplies or bit shifts.

Alternatively you could allocate 1 block of memory and assign it to a multi-dimensional array like
int *Tmp = new int[10*20];int **myArray = new int*[10];   // maybe (int*) ??for (int Index = 0; Index < 10; Index ++) {myArray[Index] = &Tmp[Index*20];}

That would give you a 2d array in 1 contiguous block.


On a side note...honestly you should probably create some sort of class to do your memory allocations or use STL ... it will save you many moons of debugging.

Cheers
-Scott
Wow, so many replies - thanks guys. So it wasn't trivial which is a relief cos I thought I was missing something. I'm not sure which approach I'll take yet - I'll probably do it the 'proper' way and use vectors or multi_array.

thanks for the help!
Quote:Original post by ToohrVyk
boost::multi_array


QFE.
have you try:
    int (*myArray)[5] = new int [2][5];

This topic is closed to new replies.

Advertisement