Search code examples
c++overloadingassignment-operatorrule-of-three

C++ Overloading assignment operator for dynamic multi dimensional array error


I'm having trouble in overloading the = operator with dynamic arrays. This is what I have so far. Also I know i havent wrote my destructor or constructor but I need to focus on this operator first:

In my header file:

#ifndef fasdf_dynn_h
#define fasdf_dynn_h

#include <iostream>
#include <fstream>
#include<string>
#include <cstdlib>
#include <vector>

using namespace std;
template <class T>

class MatrixdynVector{

public:
    template <class H>
    MatrixdynVector<H>& operator =(const MatrixdynVector<H>& c)
    {
        if (this == &c)//checks for self assignment
        {
            return *this;
        }
        else
        {
          delete [] matrix;
          matrix=new int[c.m*n];
          this->m=c.m;
          this->n=c.n;
          return *this;

        }
    }
private:
    int m,n;
    int** matrix;
};


#endif

Solution

  • I only see to major issues right now;

    number one, you are allocating c.m * this->n memory for your new data array, I assume you want to be allocating c.m * c.n memory.

    and finally, I strongly recommend you take a careful look at the copy constructor, as the delete function could cause data corruption when returning a matrix of this type.

    specifically, if you allocate this class on the stack ever, don't create an explicate copy constructor, and don't make sure that you always return a copy, the object's data will be deleted (I assume you are going to delete[] 'matrix' in your destructor) at the end, and the returned object will have 'matrix' pointing to the deleted data. I had this exact problem when I made my own matrix class.

    If you do absolutely want a multidimensional array, you can create it like this;

    matrix = new int*[c.m];
    for (int i = 0; i < c.m; i++)
      matrix[i] = new int[c.n]; // create a multi dimensional array
    
    for (int i = 0; i < c.m; i++)
      for (int j = 0; j < c.n; j++)
        matrix[i][j] = c.matrix[i][j]; // add data to it
    

    and I almost forgot, for the destructor you'll need to delete matrix with a for loop as well;

    for (int i = 0; i < c.m; i++)
      delete[] matrix[i]; // delete the second dimension of the matrix
    
    delete[] matrix; // delete the first
    

    Heres an example of a copy constructor

    MatrixdynVector<H>::MatrixdynVector(const MatrixdynVector<H>& oMat)
      : m(oMat.m), n(oMat.n), matrix(new int*[oMat.m]){
      for (int i = 0; i < m; i++){
        matrix[i] = new int[n];
        for (int j = 0; j < n; j++)
          matrix[i][j] = oMat.matrix[i][j];
      }
    }
    

    The most important parts of this copy constructor are that the argument is of const& type --if it is not done this way, the call will become recursive-- and that a duplicate is being made. Whenever dynamically allocated memory belongs to an object, great care must be taken to insure that it has a copy constructor that allocates new memory every time it is called, else the default constructor will simply give ownership of the memory to the copy as well, causing it to be deleted with the copy. You should also note that references should be use to pass an object of this type whenever possible, as reallocating memory with a copy is expensive.