ข้อผิดพลาดในการแบ่งส่วน (คอร์ทิ้ง 139)

ฉันกำลังพยายามสร้างอาร์เรย์สองมิติแบบไดนามิก (ซึ่งในกรณีนี้ฉันก็ทำได้ค่อนข้างสำเร็จ) ฉันมีคลาสที่รวมคอนสตรัคเตอร์ ตัวทำลาย และฟังก์ชันอื่น ๆ ที่เกี่ยวข้องกับการดำเนินการทางคณิตศาสตร์บนเมทริกซ์ นี่คือรหัสทั้งหมด:

  #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;
            }
        }
    }

ดังนั้นก่อนที่จะรวมคำสั่ง switch ไว้ในฟังก์ชันหลัก ทุกอย่างทำงานได้ตามปกติอย่างสมบูรณ์โดยการเรียกแต่ละฟังก์ชันด้วยตนเอง อย่างไรก็ตาม ตอนนี้คำสั่งสวิตช์ 4 คำสั่งแรกทำงานได้อย่างถูกต้อง ฉันเดาว่า แต่เมื่อฉันไปที่ 5-10 กรณี ฉันพบข้อผิดพลาดในการแบ่งส่วน (คอร์ทิ้ง 139) ฉันพยายามแก้ไขโค้ดและมันแสดงให้ฉันเห็นว่าปัญหาเกิดขึ้นเสมอเมื่อฉันกำหนดเมทริกซ์ [i][j] ให้กับอย่างอื่น เช่น ที่นี่ :

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

}

ฉันรู้ว่าต้องมีบางอย่างพร้อมพอยน์เตอร์ แต่ฉันยังเป็นมือใหม่ในการเขียนโปรแกรม โปรดช่วยฉันด้วย


person erdboden    schedule 29.09.2015    source แหล่งที่มา
comment
ก่อนที่ goto จะเข้าสู่บล็อก case 1: gdb จะพูด (ด้วย commandp a) ว่า : $6 = {matrix = 0x603010, i = 2, j = 2, codeError = 4201344} และหลัง goto menu จะบอกว่า $10 = {matrix = 0x0, i = 0, j = 0, codeError = 0} ดูเหมือนว่า adiseappear   -  person Missu    schedule 29.09.2015
comment
คุณสามารถดูได้ที่: เกิดอะไรขึ้นกับ goto และ เหตุใดจึงไม่สามารถประกาศตัวแปรในคำสั่ง switch ได้ ฉันหวังว่านี่จะช่วยคุณได้   -  person Missu    schedule 29.09.2015
comment
@Missu ขอบคุณสำหรับคำตอบ ฉันเปลี่ยนตัวแปรทั้งหมดจากคำสั่ง switch และวางไว้ที่จุดเริ่มต้นของฟังก์ชันหลัก ตอนนี้ตัวแปรจะเริ่มต้นจริงเมื่อโปรแกรมเริ่มทำงาน มันไม่สวย แต่อย่างน้อยปัญหาก็หมดไป ขอบคุณมากสำหรับการผลักดันไปในทิศทางที่ถูกต้อง!   -  person erdboden    schedule 29.09.2015


คำตอบ (1)


นี่คือปัญหา คุณกำลังสร้างวัตถุ Matrix ภายใต้ขอบเขตของ case แต่อย่างที่กล่าวไว้โดย Lightness Races in Orbit :

[...] ออบเจ็กต์ที่มีระยะเวลาการจัดเก็บอัตโนมัติจะไม่ "รั่วไหล" เมื่อคุณ goto อยู่นอกขอบเขต

และ :

[n3290: 6.6/2]: เมื่อออกจากขอบเขต (ไม่ว่าจะทำได้สำเร็จ) วัตถุที่มีระยะเวลาจัดเก็บอัตโนมัติ (3.7.3) ที่ถูกสร้างขึ้นในขอบเขตนั้นจะถูกทำลายในลำดับย้อนกลับของการก่อสร้าง [..]

ดังนั้น เมื่อ goto เสร็จสิ้นและคุณออกจากขอบเขตของ case วัตถุ Matrix ที่สร้างขึ้นภายใต้ขอบเขตจะถูกทำลาย นั่นเป็นเหตุผลว่าทำไมเมื่อคุณใช้งานหลังจากนั้น คุณจะได้รับ Segmentation fault (core dumped 139)

person Missu    schedule 29.09.2015