Search code examples
c++rule-of-three

C++ Error with big three leak in memory-pointer being freed was not allocated (not duplicate)


My code does not run correctly and I don't know how to fix it. This is not a duplicate question to someone asking what is the rule of three because that post does not help me in solving my question as in this post im using a pointer pointer array. I don't know what I did wrong in my big three functions but can someone please help me correct my mistake. The compiler is highlighting delete[] matrix[i]; in the the destructor when i=2 inside the for loop

In my header file I have:

#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:
   // MatrixdynVector()
      {
        //creates a 3 by 3 matrix with elements equal to 0
        m=3;
        n=3;

        matrix=new int*[m];

      for(int i=0;i<m;i++)
         matrix[i]=new int[n];

    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
           matrix[i][j]=0;
      }
   // MatrixdynVector(int m,int n);

    template <class H>
    MatrixdynVector<H>(const MatrixdynVector<H>& c)//copy constructor
    {
        m=c.m;
        n=c.n;

        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
    }

    template <class H>
    MatrixdynVector<H>& operator =(const MatrixdynVector<H>& c)//asignment
    {
        if (this == &c)
        {
            return *this;
        }
        else
        {
            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

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

            delete[] matrix; // delete the first*/

            return *this;
        }
    }

    ~MatrixdynVector()
    {
        if(matrix!=NULL)
        {
            for (int i = 0; i < m; i++)
               delete[] matrix[i]; // delete the second dimension of the matrix

            delete[] matrix; // delete the first

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


#endif

Solution

  • I can't compile it to verify but I think you should have something like that:

    EDIT: After compile it and chatting with question's author. Here isa working version.

    #ifndef fasdf_dynn_h
    #define fasdf_dynn_h
    
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdlib>
    
    using namespace std;
    
    template <class T>
    class MatrixdynVector {
    private:
        int m,n;
        T **matrix;
    
    public:
        MatrixdynVector();
        MatrixdynVector(int m,int n);
        MatrixdynVector(T diagonal, int n, int m);
        MatrixdynVector(const MatrixdynVector<T>& c);//copy constructor
        virtual ~MatrixdynVector();
    
        MatrixdynVector<T>& operator =(const MatrixdynVector<T>& c); //assignment
        MatrixdynVector<T> operator -();
    
        friend ostream& operator <<(ostream& outs, const MatrixdynVector<T> &obj) {
            for (int i = 0; i < obj.m; i++) {
                    for (int j = 0; j < obj.n; j++) {
                        outs << " "<< obj.matrix[i][j];
                    }
                    outs<<endl;
                }
                outs<<endl;
    
                return outs;
        }
        friend istream& operator >>(istream& in, MatrixdynVector<T> &obj) {
            for (int i = 0; i < obj.m; i++) {
                for (int j = 0; j < obj.n; j++) {
                    //if (in==cin)
                        //cout <<"input elements for element at row:"<<i<<" column:"<<j<<": ";
                    in >> obj.matrix[i][j];
                }
            }
    
            return in;
        }
    
        friend MatrixdynVector<T> operator *(const MatrixdynVector<T>& A, const MatrixdynVector<T>& B) {
            MatrixdynVector<T> product(A.m, A.n);
    
                for (int i=0;i<A.m; i++) {
                    for (int j=0;j<A.n; j++) {
                        T sum=0;
                        for (int k=0; k<A.n; k++) {
                            sum = sum+A.matrix[i][k]*B.matrix[k][j];
                        }
                        product.matrix[i][j]=sum;
                    }
                }
    
                return product;
        }
        friend MatrixdynVector<T> operator +(const MatrixdynVector<T>& a, const MatrixdynVector<T>& b) {
            MatrixdynVector<T> additon(a.m, a.n);   // you should initialize it with the good size.
    
                if((a.n != b.n) || (a.m != b.m)) {
                    // here you should throw an error : the two matrixes should be the same size.
                }
    
                for(int i=0;i<a.m;i++) {
                    for(int j=0;j<b.n;j++) {
                        additon.matrix[i][j] = a.matrix[i][j] + b.matrix[i][j];
                    }
                }
    
                return additon;
        }
        friend MatrixdynVector<T> operator -(const MatrixdynVector<T>& A, const MatrixdynVector<T>& B) {
            MatrixdynVector<T> subtract(A.m, A.n);
    
            if( A.m!= B.m || A.n!= B.n) {//if they have different rows and columns then they cant be equal
                // throw an exception.
            }
            else {
                for(int i=0;i<A.m;i++) {
                    for(int j=0;j<B.n;j++) {
                        subtract.matrix[i][j]=A.matrix[i][j]-B.matrix[i][j];
                    }
                }
            }
    
            return subtract;
    
        }
        friend bool operator ==(const MatrixdynVector<T>& A,const MatrixdynVector<T>& B) {
            //if they have different rows and columns then they cant be equal
                if( A.m!= B.m || A.n!= B.n) {
                    return false;
                }
                else {
                    for(int i=0;i<A.m; i++) {
                        for(int j=0;j<B.n; j++) {
                            if(A.matrix[i][j] != B.matrix[i][j]) {
                                cout<<A.matrix[i][j]<< " does not equal "<<B.matrix[i][j]<<endl;
                                return false;
                            }
                        }
                    }
    
                    return true;
                }
        }
    };
    
    
    template <class T>
    MatrixdynVector<T>::MatrixdynVector() {
        m=3;
        n=3;
    
        matrix=new T*[m];
    
        for(int i=0; i<m; i++) {
            matrix[i]=new T[n];
            for(int j=0;j<n;j++) {
                matrix[i][j]=0; // be careful! If T is not int, 0 can be bad initializer !!!
            }
        }
    }
    
    template <class T>
    MatrixdynVector<T>::MatrixdynVector(int x,int y) {
        m = x;
        n = y;
    
        matrix=new T*[m];
    
        for(int i=0; i<m; i++) {
            matrix[i]=new T[n];
            for(int j=0;j<n;j++) {
                matrix[i][j]=0; // be careful! If T is not int, 0 can be bad initializer !!!
            }
        }
    }
    
    template <class T>
    MatrixdynVector<T>::MatrixdynVector(T diagonal, int x, int y) {
        m=x;
        n=y;
    
        matrix=new T*[m];
    
        for(int i=0;i<m;i++) {
            matrix[i]=new T[n];
            for(int j=0;j<n;j++) {
                if(i==j) {
                    matrix[i][j]=diagonal;
                }
                else {
                    matrix[i][j]=0;// be careful! If T is not int, 0 can be bad initializer !!!
                }
            }
        }
    }
    
    template <class T>
    MatrixdynVector<T>::MatrixdynVector(const MatrixdynVector<T>& c) {
        m=c.m;
        n=c.n;
    
        matrix = new T*[m];
    
        for (int i = 0; i < m; i++) {
            matrix[i] = new T[n];
            for (int j = 0; j < c.n; j++) {
                matrix[i][j] = c.matrix[i][j]; // add data to it
            }
        }
    }
    
    template <class T>
    MatrixdynVector<T>::~MatrixdynVector() {
        if(matrix!=NULL) {
            for (int i = 0; i < m; i++) {
                delete[] matrix[i]; // delete the second dimension of the matrix
            }
    
            delete[] matrix; // delete the first
    
            matrix=NULL;
        }
    }
    
    template <class T>
    MatrixdynVector<T>& MatrixdynVector<T>::operator =(const MatrixdynVector<T>& c) {
        if(this != &c) {
            if(matrix != NULL) {
                for (int i = 0; i < m; i++) {
                    delete[] matrix[i]; // delete the second dimension of the matrix
                }
                delete[] matrix; // delete the first*/
            }
    
            m=c.m;
            n=c.n;
    
            matrix = new T*[c.m];
    
            for (int i = 0; i < c.m; i++) {
                matrix[i] = new T[c.n]; // create a multi dimensional array
                for (int j = 0; j < c.n; j++) {
                    matrix[i][j] = c.matrix[i][j]; // add data to it
                }
            }
        }
    
        return *this;
    }
    
    template <class T>
    MatrixdynVector<T> MatrixdynVector<T>::operator -() {
        MatrixdynVector<T> new_matrix(m, n);
    
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                new_matrix.matrix[i][j]=-matrix[i][j];
            }
        }
        return new_matrix;
    }
    
    #endif