Computer Science Canada

Passing 2D array by reference

Author:  HazySmoke)345 [ Thu Sep 14, 2006 7:06 pm ]
Post subject:  Passing 2D array by reference

Well, yes. I know how to pass a 1D array by reference. I can just use a pointer for the first element and I'm still able to refer to its elements by using the [] symbol.

Now... how do you pass 2D arrays? I tried to have two stars before the variable names and I tried to use its elements with square brackets, like this.

code:
void someFunction(int** variable)
  { variable[3][5] = 1; }


And the program crashed.

Author:  wtd [ Thu Sep 14, 2006 11:14 pm ]
Post subject: 

Was the array you passed in properly allocated?

Author:  OneOffDriveByPoster [ Fri Sep 15, 2006 8:05 am ]
Post subject:  Re: Passing 2D array by reference

HazySmoke)345 wrote:
Well, yes. I know how to pass a 1D array by reference. I can just use a pointer for the first element and I'm still able to refer to its elements by using the [] symbol.

Now... how do you pass 2D arrays? I tried to have two stars before the variable names and I tried to use its elements with square brackets, like this.

code:
void someFunction(int** variable)
  { variable[3][5] = 1; }


And the program crashed.


Use int **var with dynamically allocated 2-D arrays (where it is a pointer-to pointer-to-int).
I suspect the 2-D array you are passing is declared like so: int v[X][Y]; (something else).

Properly-allocated multidimenional arrays of both types will give unexpected results if you pass them wrong.

Author:  wtd [ Fri Sep 15, 2006 1:09 pm ]
Post subject: 

Problems with multi-dimensional arrays will eventually teach you to love code like the following.

code:
#include <iostream>
#include <sstream>

using namespace std;

template <typename T>
class Matrix2D
{
   private:
      size_t m_rows, m_cols;
      T *m_data;
          
          size_t max_string_length() const;

   public:
      explicit Matrix2D();
      explicit Matrix2D(size_t rows, size_t cols);
      explicit Matrix2D(size_t rows, size_t cols, T initial_value);
          Matrix2D(const Matrix2D<T>& m);

          Matrix2D<T>& operator=(const Matrix2D<T>& m);
          
      virtual ~Matrix2D()
      {
         delete [] m_data;
      }     

      T &operator()(size_t row, size_t col);
      T operator()(size_t row, size_t col) const;
          
          template <typename _T>
          friend ostream& operator<<(ostream& out, const Matrix2D<_T>& m);
          
          size_t rows() const;
          size_t cols() const;
};

int main()
{
   Matrix2D<int> foo(10, 10, 0);
   
   foo(8, 3) = 42;
   foo(9, 9) = 523;
   
   cout << foo << endl;

   return 0;
}

template <typename T>
Matrix2D<T>::Matrix2D()
: m_rows(0), m_cols(0), m_data(new T[0])
{
}

template <typename T>
Matrix2D<T>::Matrix2D(size_t rows, size_t cols)
: m_rows(rows), m_cols(cols), m_data(new T[rows * cols])
{
}

template <typename T>
Matrix2D<T>::Matrix2D(size_t rows, size_t cols, T initial_value)
: m_rows(rows), m_cols(cols), m_data(new T[rows * cols])
{
   for (T *start = m_data; start != m_data + m_rows * m_rows; start++)
   {
      *start = initial_value;
   }
}

template <typename T>
Matrix2D<T>::Matrix2D(const Matrix2D<T>& m)
: m_rows(m.m_rows), m_cols(m.m_cols),
  m_data(new T[m.m_rows * m.m_cols])
{
   for (size_t i = 0; i < m.m_rows * m.m_cols; i++)
   {
      m_data[i] = m.m_data[i]; 
   }
}
       
template <typename T>   
Matrix2D<T>& Matrix2D<T>::operator=(const Matrix2D<T>& m)
{
   delete [] m_data;
   
   m_rows = m.m_rows;
   m_cols = m.m_cols;
   m_data = new T[m_rows * m_cols];
   
   for (size_t i = 0; i < m_rows * m_cols; i++)
   {
      m_data[i] = m.m_data[i]; 
   }
   
   return *this;
}

template <typename T>
T &Matrix2D<T>::operator()(size_t row, size_t col)
{
   return m_data[row * m_cols + col];
}

template <typename T>
T Matrix2D<T>::operator()(size_t row, size_t col) const
{
   return m_data[row * m_cols + col];
}

template <typename T>
ostream& operator<<(ostream& out, const Matrix2D<T>& m)
{
   size_t max_len = m.max_string_length();

   for (int r = 0; r < m.m_rows; r++)
   {
      for (int c = 0; c < m.m_cols; c++)
          {      
             stringstream ss;
                
                 ss << m(r, c);
                
                 size_t cur_len = ss.str().length();
          
             for (int i = 0; i < max_len - cur_len; i++)
                 {
                    out << " ";
                 }
          
             out << m(r, c);
                
                 if (c == m.m_cols - 1)
                 {
                    if (r != m.m_rows - 1)
                        {
                       out << endl;
                        }
                 }
                 else
                 {
                    out << " | ";
                 }
          }
   }
   
   return out;
}

template <typename T>
size_t Matrix2D<T>::max_string_length() const
{
   size_t len = 0;
   
   for (int r = 0; r < m_rows; r++)
   {
      for (int c = 0; c < m_cols; c++)
          {
             stringstream ss;
                
                 ss << (*this)(r, c);
                
                 size_t cur_len = ss.str().length();
                
                 if (cur_len > len)
                 {
                    len = cur_len;
                 }
          }
   }
   
   return len;
}

template <typename T>
size_t Matrix2D<T>::rows() const
{
   return m_rows;
}

template <typename T>
size_t Matrix2D<T>::cols() const
{
   return m_cols;
}


Author:  md [ Fri Sep 15, 2006 5:55 pm ]
Post subject: 

Did you write that yourself wtd? And if so... mind if I make a copy of the code in case of need?

Author:  wtd [ Fri Sep 15, 2006 6:04 pm ]
Post subject: 

Cornflake wrote:
Did you write that yourself wtd?


Yes, I did. Smile

Author:  HazySmoke)345 [ Sat Sep 16, 2006 11:36 pm ]
Post subject: 

Quote:
Was the array you passed in properly allocated?

No, it wasn't...

code:
Use int **var with dynamically allocated 2-D arrays (where it is a pointer-to pointer-to-int).
I suspect the 2-D array you are passing is declared like so: int v[X][Y]; (something else).

Properly-allocated multidimenional arrays of both types will give unexpected results if you pass them wrong.

I see... thanks.

Too bad I don't have too many bits to gave away Sad I gave them all to one of the guys in the VB boards, but I'll just distribute whatever's left.


: