Topic: how to allocated two dim array on free store?


Author: Heinz Huber <Heinz.Huber@elbanet.co.at>
Date: 2000/11/29
Raw View

Dylan Nicholson wrote:

[snipped alternative matrix class]

> Well you could do better than this using a matrix_row class and a
> matrix class together, that way matrix::operator [] can return a
> reference to a matrix_row, and matrix_row::operator [] can return a
> reference to the actual value needed, allowing to do...
>
> matrix<int> arg(25,35);
> arg[7][5] = 5;
>
> Now all that's needed to generalise it for an n-dimensional matrix.

What do you think about the following (untested and without guarantee):

template <typename val, int dim> class matrix {
public:
    typedef matrix< val, dim - 1 > valType;

private:
    int size;
    Vector < valType > values;

public:
    matrix(int* sizes) : size(*sizes), values(*sizes, valType(sizes +
1)) /* [1] */ {}
    valType& operator [] (int i) { return values[i]; }
};

template <typename val> class matrix< 1 > {
public:
    typedef val valType;

private:
    int size;
    Vector < val > values;

public:
    matrix(int* sizes) : size(*sizes), values(*sizes) {}
    valType& operator [] (int i) { return values[i]; }
};


I'm not sure about the signature of operator[] and of the 2nd parameter
of constructor [1]. But the principle should be clear.

Regards,
Heinz

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Dylan Nicholson <dnich@my-deja.com>
Date: 2000/11/27
Raw View
In article <3A1B02A6.B168C82E@evtechnology.com>,
  James Dennett <james@evtechnology.com> wrote:
> ln wrote:
> >
> > James Dennett wrote in message
<3A193A8D.39909B0C@evtechnology.com>...
>
> How about the following (untested) code?
>
> #include <vector>
>
> template <typename ElementType>
> class matrix
> {
> public:
>   matrix(int numberOfRows, int numberOfColumns)
>   : m_numberOfRows(numberOfRows),
>     m_numberOfColumns(numberOfColumns),
>     m_elements(numberOfRows*numberOfColumns) { }
>
>   ElementType &operator () (int row, int column)
>   { return m_elements[row*m_numberOfColumns + column]; }
>
>   const ElementType &operator () (int row, int column) const
>   { return m_elements[row*m_numberOfColumns + column]; }
>
> private:
>   const int m_numberOfRows;
>   const int m_numberOfColumns;
>   std::vector<ElementType> m_elements;
> };
>
> which you can use like
>
> matrix<int> arg(25,35);
> arg(7,5) = 5;
>

Well you could do better than this using a matrix_row class and a
matrix class together, that way matrix::operator [] can return a
reference to a matrix_row, and matrix_row::operator [] can return a
reference to the actual value needed, allowing to do...

matrix<int> arg(25,35);
arg[7][5] = 5;

Now all that's needed to generalise it for an n-dimensional matrix.
Dylan


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Dennett <james@evtechnology.com>
Date: 2000/11/21
Raw View
ln wrote:
>
> James Dennett wrote in message <3A193A8D.39909B0C@evtechnology.com>...
> >> presumably what we need is a pointer to pointer returned (ie int**)
> >
> >Not quite right.  You want a pointer to an array of arrays, but C++ does
> not
> >have pointers to array, it uses a pointer to the first element instead.
> So,
> >instead of a pointer to an array of arrays, we have a pointer to the first
> >element of the array of arrays, i.e., a pointer to an array, i.e., a
> pointer
> >to the first element of that array, i.e., a pointer to an integer.
> >
>
> however in the end it will be int**; otherwise one could not perform
> something like
> int* ary;
> //allocate memm then...
> ary[7][5]=5;

That holds only if you allocated an array of pointers to array of int, as
in

int **arg = new int *[25];
for (int i = 0; i < 25; ++ i) arg[i] = new int[35];

That's not a two-dimensional array by any sane definition, although it
does allow you to use nice syntax.  Clearing up the memory will be a
pain.  (See class matrix below for an alternative which avoids that
problem.)  This form does allow you to handle non-rectangular structures;
it could be used (inefficiently) to implement (say) upper-triangular
matrices.

> but if ary was int** thing goes fine.

Not if you allocated a block of x*y integers, because then you don't
have a pointer to a pointer, you have a pointer to an (array of) int.

How about the following (untested) code?

#include <vector>

template <typename ElementType>
class matrix
{
public:
  matrix(int numberOfRows, int numberOfColumns)
  : m_numberOfRows(numberOfRows),
    m_numberOfColumns(numberOfColumns),
    m_elements(numberOfRows*numberOfColumns) { }

  ElementType &operator () (int row, int column)
  { return m_elements[row*m_numberOfColumns + column]; }

  const ElementType &operator () (int row, int column) const
  { return m_elements[row*m_numberOfColumns + column]; }

private:
  const int m_numberOfRows;
  const int m_numberOfColumns;
  std::vector<ElementType> m_elements;
};

which you can use like

matrix<int> arg(25,35);
arg(7,5) = 5;

No need to worry about cleaning up resources (let std::vector do that)
and it would be easy to change to add bounds checking if you wanted,
or to initialize all elements if that's your preference.  Not a pointer
in sight -- the Standard Library is your friend.

I'm sure that more rigorous and feature-rich versions of class matrix
can be found all over the place.  The one above was typed just for
this message.

Hope this helps.

-- James Dennett <jdennett@acm.org>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]