Question

I have a homework assignment asking me to implement a matrix class with that uses dynamic allocation to store its elements. The class should allow the addition and substraction. It needs to free memory that it no longer needs to store elements.

My idea was to create two classes: matrix class and element class. The element class has two properties (a key and the address to the next element). The proble is, should I store all the elements in the matrix class somehow or only an address to the first element, and make all the operation based on that first element? What do you think of my approach?

Was it helpful?

Solution

Perhaps if you say what you mean you wouldn't get people answering what you wrote.

Your matrix needs to dynamically allocate to store its members.

The best way to do this is not to be two-dimensional but to be single-dimensional in its allocation. You need M * N elements so allocate M*N in one go.

To find element( i, j ), it is actually element ( i * M ) + j.

Thus you have something like, if the elements are double

class Matrix
{
private:
     double * m_mem;
     size_t m_width;
     size_t m_height;
public:
     Matrix( size_t width, size_t height );
     ~Matrix();

     double operator()( size_t i, size_t j ) const
     {
         return m_mem[ i * m_width + j ];
     }
     double& operator()( size_t i, size_t j ) 
     {
         return m_mem[ i * m_width + j ];
     }

     size_t width() const
     {
         return m_width;
     }

     size_t height() const
     {
         return m_height;
     }

     Matrix(Matrix const& other ); // you implement
     Matrix& operator=( Matrix const& other ); // you implement
};
  • You will want 2 overloads for operator(), a non-const one for setting these members.
  • You might wish to bounds check.

Allocate thus:

     Matrix::Matrix( size_t width, size_t height ) :
        m_mem( new double[width * height] ),
        m_width( width ),
        m_height( height )
     {
     }

Free thus:

     Matrix::~Matrix()
     {
           delete [] m_mem;
     }

You will need to manage the copying and assigning, given the rule of 3.

It is not possible to deallocate part of your matrix.

If you want to make the Matrix generic, you must write a template. But I don't know if you have yet learnt how to write templates.

For addition and subtraction, you could use class members or:

     Matrix operator+( Matrix const& left, Matrix const& right )
     {
         assert( left.width == right.width );
         assert( left.height == right.height );
         Matrix sum( left.width, left.height );
         for( size_t i = 0; i < left.width; ++i )
         {
             for( size_t j = 0; j < left.height; ++j )
             {
                 sum( i, j ) = left( i, j ) + right( i, j );
             }
         }
         return sum; // in C++11 return std::move(sum) and return-type Matrix&&
     }

If you used class members (or make the operator a friend) you can make use of your internal structure by running through every element in the one-dimensional arrays in a single (rather than nested) loop. It won't improve the complexity of the algorithm which is still height * width, although it may be a tiny bit faster due to the pointer arithmetic.

OTHER TIPS

You don't need "element class". You don't need "address of the next element". IMO, you're making this needlessly complicated.

A matrix is a 2D array.
A simplest way to represent 2D array with numRows rows and numColumns columns is to make 1D array with size numRows * numColumns.
In such array offset of individual element (rowIndex, columnIndex) can be calculated as rowIndex * numCOlumns + columnIndex, where both indexes are zero-based. And you do know how to allocate 1D array, right?

Class Matrix:
{
private:
int**m;
public:
Matrix();//allocate memory
Realocate_memory(int**, int rows, int cols); //in case you want to modify the size of the matrix - this will be the most complicated part as you need to handle memory allocation.
Free(int**m, int rows, int cols);

// other methods....
}

the tricky part here is deleting the not used elements- since you you have to keep the matrix structure there are a few constraints: - you can only delete entire rows/columns - you may move data around is that is allowed so that you end up with full rows/cols of unused elements - but personally I wouldn't bother with this approach

You can also allocate more memory when you run out of space - here you can take the Dynamic array approach: - allocate a new matrix 2x size - copy the old one in the new one - free the old one.

hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top