how to use a dynamically created one-dimensional array by a two-dimension array reference only with standard library?

StackOverflow https://stackoverflow.com/questions/8573645

  •  22-03-2021
  •  | 
  •  

Question

how to use a dynamically created one-dimensional array by a two-dimension array reference only with standard library?

could it be done by construct overloading of operator [] ?

example: i want to form a matrix by creating a one-dimension array and then use it in the form of using a two-dimension array.

// in class, a matrix created by:
p = new double[m*n]();

when using it, I'd like to use it like this:
for(i=0; i<10; i++)
    for(j=0; j<10; j++)
        a[i][j] = 0.0;

i thought of using operator overloading of operator [] and a variable test to testify if the "[]" appeared for the first time or not, but above turned out to be a

error: "invalid types double[int] for array subscript "

is that possible to do so?

Was it helpful?

Solution

It's easy to do this with operator() if you don't mind Fortran-like syntax. I like to use a helper class like this:

template <class T>
class Indexer2D
{
public:
    Indexer2D(size_t w, size_t h, T *theData) :
        width(w), height(h), data(theData)
    { }

    T& operator() (size_t row, size_t col)
    {
        return data[(width * row) + col];
    }
private:
    size_t width;
    size_t height;
    T *data;
};

Your code would look like:

p = new double[m*n]();

Indexer2D<double> pMatrix(m, n, p);
pMatrix(1,4) = 23.9;

This gives you nice syntax with minimal memory allocation. It doesn't check your bounds, but it would be easy to do so. If you need minimal weight, you don't have to store the height either.

OTHER TIPS

I suggest either using manual index calculations:

a = new double[m*n]();

for(i=0; i<10 && i<m; i++)
    for(j=0; j<10 && j<n; j++)
        a[i*n+j] = 0.0; 

The reverse calc would be: i = index/n, j = index % n

Alternatively, use valarray:

#include <valarray>
// ....

     a[std::slice(i, n, m)][j] = 0.0;

Better results can be achieved using std::gslice (which is generalized slice, accepting multiple dimensions). I don't have the time to work out a full example now.

Here is a link to quite a powerful sample by N. Josuttis:

If you can use extra memory, you can do this:

// Allocate 1D array
double * p = new double[m*n]();
// Allocate pointers for 2D reference
double ** p2D = new double *[m];

// set 2D pointers to allocated memory
for (i = 0; i < m; i++)
    p2D[i] = &p[i * n];

for(int i=0; i<m; i++)
    for(int j=0; j<n; j++)
        p2D[i][j] = 0.0; 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top