涼宮こなた 2017-09-13 08:05 采纳率: 100%
浏览 881
已采纳

帮忙看看这个程序出了什么问题

本菜写了一个小程序
能够创建一个矩阵,规定长宽,并进行矩阵之间的加减运算
代码如下

 #include<iostream>
using namespace std;

class matrix                                                                //创建矩阵类 
{
    private:
        int lines;
        int rows;
        int **num;                                                          //建立二重数组
    public:
        matrix(int a,int b)                                                 //构造函数
        {
            lines=a;
            rows=b;
            cout<<"矩阵初始化"<<endl;
            num=new int*[lines];
            int x,y;
            for(y=0;y<lines;y++)
            {
                num[y]=new int[rows];                                       //循环完成new申请内存 
            }
        }
        /*matrix(matrix& father)                                            //拷贝构造函数 
        {
            cout<<"调用拷贝构造函数"<<endl;
            lines=father.lines;
            rows=father.rows;
            int x,y;
            for(y=0;y<lines;y++)
            {
                for(x=0;x<rows;x++)
                {
                    num[x][y]=father.num[x][y];                             //循环读入矩阵元素 
                }
            }
        }*/
        void in();                                                          //输入函数 
        void out();                                                         //输出函数 
        int get_num(int x,int y)                                            //取用指定元素的函数(内联)
        {
            return num[x][y];
        }
        void operate(int mode,matrix m1,matrix m2);                         //运算函数,包含加和减 
        ~matrix()                                                           //析构函数 释放矩阵空间 
        {

        }
        void matrix_free();                                                 //释放矩阵空间函数 
};

void matrix::matrix_free()
{
    int i;
    for(i=0;i<lines;i++)
    {
        delete []num[i];                                
    } 
    delete []num;
}

void matrix::in()
{
     cout<<"请按顺序输入矩阵元素:"<<endl;
     int x,y;
     for(y=0;y<lines;y++)
     {
        for(x=0;x<rows;x++)
        {
            cin>>num[x][y];                                                 //循环输入矩阵元素 
        }
     }
}

void matrix::out()                                                          //此函数可以按格式输出矩阵 
{
    int x,y;
    for(y=0;y<lines;y++)
    {
        for(x=0;x<rows;x++)
        {
            cout<<num[x][y];
            if(x!=rows-1)
            {
                cout<<" ";
            }
        }
        cout<<endl;
    }
}

void matrix::operate(int mode,matrix m1,matrix m2)                          //运算函数,mode=1代表加,mode=-1代表减,m1,m2为待处理矩阵
{
    int x,y;
    for(y=0;y<lines;y++)
    {
        for(x=0;x<rows;x++)
        {
            num[x][y]=m1.get_num(x,y)+mode*m2.get_num(x,y);                 //运算部分
        }
    }
}

int main(void)
{
    int a=0,b=0;
    cout<<"输入矩阵大小(行 列):"<<endl;
    while(a<=0||b<=0)
    {
        cin>>a>>b;
        if(a<=0||b<=0)
        {
            cout<<"输入错误,重新输入:"<<endl;
        }
    }
    matrix A1(a,b),A2(a,b),A3(a,b);                                         //创建三个矩阵 
    A1.in();                                                                //输入初始化
    A2.in();                                                                
    A3.operate(1,A1,A2);                                                    //A3=A1+A2 
    cout<<"矩阵和:"<<endl; 
    A3.out();                                                               //输出 
    A3.operate(-1,A1,A2);                                                   //A3=A1-A2
    cout<<"矩阵差:"<<endl; 
    A3.out();                                                               //输出
    A1.matrix_free();                                                       //释放矩阵空间 
    A2.matrix_free();
    A3.matrix_free(); 
}

此程序目前问题有三个
1.拷贝构造函数出错,只能注释掉,否则输入完两个矩阵后回车程序未响应
2.释放矩阵空间的不能写在析构函数里,否则输出结果不正确(A3=A1-A2的最后一行)
3.输入矩阵的列不能大于行,否则输入完第一行数字并回车后程序未响应

请前辈指导,谢谢

  • 写回答

2条回答 默认 最新

  • shifenglv 2017-09-13 12:45
    关注

    第一个问题,num没有分配空间就进行赋值,导致出错。类对象作为方法的参数时,是按照“传值”的方式传递的,也就是说,会复制一个副本,这时会调用拷贝构造函数(void matrix::operate(int mode,matrix m1,matrix m2) 这里的m1、m2是A1、A2的副本而不是指针)。因为副本m1、m2没有经过构造函数初始化,所以副本中的num是没有分配空间的,而你再拷贝构造函数中引用num,所以会出错。修改:在拷贝构造函数中先检查nun指针是否为null,如果是,则在拷贝构造函数中为num分配空间。
    第二个问题,析构函数在类对象的生命周期结束的时候或者被delete掉的时候才会被调用,所以,在析构函数中释放动态分配的内存是完全可以的。问题不在于你在析构函数中释放内存,而在于以“传值”的方式传递类参数。上面说过,参数m1\m2是A1\A2的副本,这个副本的生命周期在方法调用结束之后就完了,所以第一次使用A3.operate(1,A1,A2)结束时会调用析构函数,来清理m1\m2。按理说,m1\m2是A1\A2的副本,清理m1\m2并不会影响A1\A2,问题蹊跷的地方在于,m1\m2和A1\A2之间共享了一块内存,这个内存就是num所指向的空间。为什么会这样
    ?因为m1=A1,m2=A2时,意味着m1.num=A1.num,m2.num=A2.num。如果num是一个非指针类变量,那么m1.num就是A1.num的副本,现在的情况是,num是指针,指针之间的赋值,意味着大家都指向同一块内存。在你释放掉m1.num指向的内存就是释放A1.num指向的内存。修改:不在析构函数中释放内存,或者方法中的参数传递改为“传址”,如void matrix::operate(int mode,matrix& m1,matrix& m2)。
    第三个问题,其实就是数组元素访问出现越界。修改,in/out方法中的,for循环,外层循环应该是矩阵的行,用x作下标。内循环应该是矩阵的列用y做下标。而你刚好相反了。
    最后,对矩阵的运算其实可以运用运算符的重载,这样要方便的多。对于拷贝构造函数,除非你知道你要干什么,否则慎用。在你这段程序中,我没看到使用拷贝构造函数的必要。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 虚拟机打包apk出现错误
  • ¥30 最小化遗憾贪心算法上界
  • ¥15 用visual studi code完成html页面
  • ¥15 聚类分析或者python进行数据分析
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝