2

I am trying to make a dynamic bidimensional array (in which case i pretty much did successfully). I have a class which includes some constructors, a destructors and other functions that deals with arithmetic operations on the matrix. so here is the whole code:

  #include <iostream>
#include <stdint.h>
using namespace std; 
int n,m,input,i,j;

class Matrix{
    int **matrix;
    int i,j,codeError;
    public:
        Matrix();
        Matrix(int);
        Matrix(int, int);
        Matrix(const Matrix&, int, int);
        ~Matrix();
        void setIJ(int, int);
        int getIJ(int, int);
        void set(int,int);
        void position();
        void plus(const Matrix&,const Matrix&,int, int);
        void minus(const Matrix&,const Matrix&,int, int);
        void multiply(const Matrix&,const Matrix&,int, int);
        //void multiply(int,int,int);
        void print(int, int);
    };
Matrix a,b,c,d,e;
Matrix::Matrix(){

        matrix=NULL;
        i=0;
        j=0;
    }
Matrix::Matrix(int n){
    matrix=new int*[n];
    for(i=0;i<n;i++)
    matrix[i]=new int[n];
    for (int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j)
            matrix[i][j]=1;
            else matrix[i][j]=2;
            }
        }
    }

Matrix::Matrix(int m, int n){
    matrix=new int*[n];
    for(i=0;i<n;i++)
    matrix[i]=new int[m];
    for (int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(i==j)
            matrix[i][j]=0;
            else matrix[i][j]=1;
            }
        }
}


Matrix::Matrix(const Matrix &obj,int n, int m)

    {
        matrix=new int*[n];
    for(i=0;i<n;++i)
    matrix[i]=new int[m];
        for (int i=0;i<n;i++){
            for (int  j=0; j<n; j++){
                    matrix[i][j]=obj.matrix[i][j];
                }
            }
        }

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


void Matrix::set(int n, int m){
     matrix=new int*[n];
    for(i=0;i<n;++i)
    matrix[i]=new int[m];

    for ( i=0;i<n;i++){
        for( j=0;j<m;j++){
            cin>>matrix[i][j];
            }
        }
    }
void Matrix::setIJ(int i, int j){
        int num;
        cout<<"matrix[i][j]="<<endl;
        cin>>num;
        matrix[i][j]=num;
        }


int Matrix::getIJ(int i, int j){
    return matrix[i][j];
    }

void Matrix::plus(const Matrix &obj,const Matrix &tmp,int n,int m){
    matrix=new int*[n];
    for(i=0;i<n;i++)
    matrix[i]=new int [m];
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            matrix[i][j]=tmp.matrix[i][j]+obj.matrix[i][j];
        }
    }
}

void Matrix::minus(const Matrix &obj,const Matrix &tmp,int n,int m){
    matrix=new int*[n];
    for(i=0;i<n;i++)
    matrix[i]=new int [m];
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            matrix[i][j]=tmp.matrix[i][j]-obj.matrix[i][j];
        }
    }
}

void Matrix::multiply(const Matrix &obj,const Matrix &tmp,int n,int m){
    matrix=new int*[n];
    for(i=0;i<n;i++)
    matrix[i]=new int [m];
    int temp1=0,temp2=0;
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            for(int k=0;k<n;k++){
            temp1=tmp.matrix[i][k];
            temp2=obj.matrix[k][j];
            matrix[i][j]+=temp1*temp2;
            }
        }
    }
}

/*void Matrix::multiply(int n,int m,int scalar){

    matrix=new int*[n];
    for(i=0;i<n;i++)
    matrix[i]=new int [m];
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            matrix[i][j]*=scalar;
        }
    }
}*/

void Matrix::print(int n, int m){
    for(int i=0;i<n;i++){
        cout<<endl;
        for(int j=0;j<m;j++){
            cout<<" "<<matrix[i][j];
            }
        }
    }

int main(){
        menu:
    cout<<"menu"<<endl;
    cout<<"1.Constructor without parameters"<<endl;
    cout<<"2.Constructor 1 parameter"<<endl;
    cout<<"3.Constructor 2 parameters"<<endl;
    cout<<"4.copy constructor"<<endl;
    cout<<"5.change number on IJ position"<<endl;
    cout<<"6.what is the number on IJ position"<<endl;
    cout<<"7.adition"<<endl;
    cout<<"8.substraction"<<endl;
    cout<<"9.multiply"<<endl;
    cout<<"10.print"<<endl;

    cin>>input;
    switch(input){
        case 1:{
            Matrix a;
            cout<<"write n si m"<<endl;
            cin>>n>>m;
            a.set(n,m);
            goto menu;
            }
        case 2:{
            Matrix b(3);
            goto menu;
            }
        case 3:{
            Matrix c(3,4);
            goto menu;
            }
        case 4:{
            Matrix d(a);
            goto menu;
            }   
        case 5:{
            cout<<"write i,j"<<endl;
            cin>>i>>j;
            a.setIJ(i,j);
            goto menu;
            }
        case 6:{
            cout<<"itnrodu i,j"<<endl;
            cin>>i>>j;
            a.getIJ(i,j);
            goto menu;
            }
        case 7:{
            e.plus(a,d,n,m);
            goto menu;
            }
        case 8:{
            e.minus(a,d,n,m);
            goto menu;
            }
        /*case 9:{

            }*/
        case 10:{
            a.print(n,m);
            b.print(3,3);
            c.print(3,4);
            d.print(n,m);
            e.print(n,m);

            goto menu;
            }
        }
    }

so before including the switch statement in the main function, everything worked perfectly normal by manually calling each function. now however, the first 4 switch statements work properly i guess, but when i go to the 5-10 cases, i get the Segmentation fault (core dumped 139). i tried debugging the code and it shows me that the problem is always when i assign the matrix[i][j] to something else, for example here :

void Matrix::setIJ(int i, int j){
    int num;
    cout<<"matrix[i][j]="<<endl;
    cin>>num;
    **matrix[i][j]=num;**<-here
    }

or here:

void Matrix::plus(const Matrix &obj,const Matrix &tmp,int n,int m){
matrix=new int*[n];
for(i=0;i<n;i++)
matrix[i]=new int [m];
for(i=0;i<n;i++){
    for(j=0;j<m;j++){
        **matrix[i][j]=tmp.matrix[i][j]+obj.matrix[i][j];**<-here
    }
}

}

i know something's gotta be with pointers but i am still a rookie in programming please help me

erdboden
  • 23
  • 5
  • Before the `goto` into the `case 1:` block, gdb says (with the command`p a`) that : `$6 = {matrix = 0x603010, i = 2, j = 2, codeError = 4201344}` and after the `goto menu` it says that `$10 = {matrix = 0x0, i = 0, j = 0, codeError = 0}`. Seems like `a`diseappear. – Missu Sep 29 '15 at 14:27
  • You can take a look on : [what's wrong with goto](http://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto) and [why can't variables be declared in a switch statement](http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement). I hope this will help you. – Missu Sep 29 '15 at 15:21
  • @Missu thanks for the reply. i changed all the variables from the switch statement and put them to the start of the main function, now the variables actually initialize when the program starts. it's not pretty but hey, at least the problem is gone. thanks a lot for the push in the right direction! – erdboden Sep 29 '15 at 15:45

1 Answers1

1

Here is the problem. You're creating Matrix objects under case's scope. But like said by Lightness Races in Orbit :

[...] objects with automatic storage duration are not "leaked" when you goto out of their scope

and :

[n3290: 6.6/2]: On exit from a scope (however accomplished), objects with automatic storage duration (3.7.3) that have been constructed in that scope are destroyed in the reverse order of their construction. [..]

So, when the goto is done and you left the case's scope, Matrix objects created under the scope will be destroy. That's why when you're using it after, you obtain a Segmentation fault (core dumped 139)

Community
  • 1
  • 1
Missu
  • 505
  • 3
  • 15