免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2694 | 回复: 9
打印 上一主题 下一主题

矩阵计算时重载+的问题:改变了第一操作数的值 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-22 18:17 |只看该作者 |倒序浏览
部分代码如下,全部代码见二楼:

#include<iostream>
using namespace std;

class matrix {
        double * elems;
        short row,col;
    public:
        matrix(short vrow,short vcol) ;
        ~matrix();
        void print();
        int set (short vrow,short vcol,double val);
        double operator () (short,short);
        friend matrix operator + (matrix,matrix);
        ......
};

matrix::matrix(short vrow,short vcol) {
        row = vrow;
        col = vcol;
        elems = new double[row * col];
}
matrix::~matrix() {
        delete elems;
}

double matrix:perator () (short vrow,short vcol) {
        return vrow < row && vcol < col && vrow >= 0 && vcol >= 0 ? elems[vrow * col + vcol] : 0.0;
}
int matrix::set (short vrow,short vcol,double val) {
        if (vrow >= 0 && vrow < row && vcol >= 0 && vcol < col ) {
                elems[vrow * col + vcol] = val;
                return 0;
        } else {
                return 1;
        }
}
matrix operator + (matrix m1,matrix m2) {
        matrix m3(m1.row,m1.col);
        if (m1.row != m2.row || m1.col != m2.col ) return m3;
        for( int i = 0 ; i < m1.row  ; i++ ) {
                for ( int j = 0 ; j < m1.col ; j++ )
                        m3.set(i,j,m1(i,j) + m2(i,j));
        }
        return m3;
}

int main() {

        matrix m1(3,4),m2(3,4),m3(2,3),m4(3,4),m5(2,4),m6(3,4);
        m1.set(0,0,1);
......
        m3.set(1,2,6);
        m3.print();
        cout << "----------------\n";
        m1.print();
        cout << "----------------\n";
        m2.print();
        cout << "----------------\n";
        m4 = m1 + m2;
        m4.print();
        cout << "----------------\n";
        m6 = m1 - m2;
        m6.print();
        m5 = m3 * m1;
        m5.print();
}


结果在运行到  m4 = m1 + m2;时,m1.elems[0]的值被改变了。运行报错如下:
*** glibc detected *** ./a.out: double free or corruption (!prev): 0x09795008 ***
======= Backtrace: =========
/lib/libc.so.6[0x17aac1]
/lib/libc.so.6(cfree+0x90)[0x17e0f0]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x24e06f1]
./a.out(__gxx_personality_v0+0x317)[0x8048917]
./a.out[0x80493f1]
/lib/libc.so.6(__libc_start_main+0xe0)[0x127390]
./a.out(__gxx_personality_v0+0x41)[0x8048641]
======= Memory map: ========
00110000-00111000 r-xp 00110000 00:00 0          [vdso]
00111000-00264000 r-xp 00000000 fd:00 1067801    /lib/libc-2.7.so
00264000-00266000 r-xp 00153000 fd:00 1067801    /lib/libc-2.7.so
00266000-00267000 rwxp 00155000 fd:00 1067801    /lib/libc-2.7.so
00267000-0026a000 rwxp 00267000 00:00 0
00296000-002b1000 r-xp 00000000 fd:00 1067800    /lib/ld-2.7.so
002b1000-002b2000 r-xp 0001a000 fd:00 1067800    /lib/ld-2.7.so
002b2000-002b3000 rwxp 0001b000 fd:00 1067800    /lib/ld-2.7.so
00d68000-00d8f000 r-xp 00000000 fd:00 1067805    /lib/libm-2.7.so
00d8f000-00d90000 r-xp 00026000 fd:00 1067805    /lib/libm-2.7.so
00d90000-00d91000 rwxp 00027000 fd:00 1067805    /lib/libm-2.7.so
0242d000-0250d000 r-xp 00000000 fd:00 227099     /usr/lib/libstdc++.so.6.0.8
0250d000-02511000 r-xp 000df000 fd:00 227099     /usr/lib/libstdc++.so.6.0.8
02511000-02512000 rwxp 000e3000 fd:00 227099     /usr/lib/libstdc++.so.6.0.8
02512000-02518000 rwxp 02512000 00:00 0
07fe6000-07ff1000 r-xp 00000000 fd:00 1067812    /lib/libgcc_s-4.1.2-20070925.so.1
07ff1000-07ff2000 rwxp 0000a000 fd:00 1067812    /lib/libgcc_s-4.1.2-20070925.so.1
08048000-0804a000 r-xp 00000000 fd:00 1202293    /home/liuhy/c/9/a.out
0804a000-0804b000 rw-p 00001000 fd:00 1202293    /home/liuhy/c/9/a.out
09795000-097b6000 rw-p 09795000 00:00 0
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7fa3000-b7fa5000 rw-p b7fa3000 00:00 0
b7fb6000-b7fb7000 rw-p b7fb6000 00:00 0
bfe07000-bfe1c000 rw-p bffea000 00:00 0          [stack]
已停止

[ 本帖最后由 welcome008 于 2008-5-22 18:19 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-05-22 18:19 |只看该作者
#include<iostream>
using namespace std;

class matrix {
        double * elems;
        short row,col;
    public:
        matrix(short vrow,short vcol) ;
        ~matrix();
        void print();
        int set (short vrow,short vcol,double val);
        double operator () (short,short);
        friend matrix operator + (matrix,matrix);
        friend matrix operator - (matrix,matrix);
        friend matrix operator * (matrix,matrix);
};

matrix::matrix(short vrow,short vcol) {
        row = vrow;
        col = vcol;
        elems = new double[row * col];
}
matrix::~matrix() {
        delete elems;
}
void matrix::print() {
        for(int i = 0; i < row * col ; i++) {
                if ( i > 0 && i % row == 0 ) cout << "\n";
                cout << elems << "\t";
        }
        cout << "\n";
}
double matrix:perator () (short vrow,short vcol) {
        return vrow < row && vcol < col && vrow >= 0 && vcol >= 0 ? elems[vrow * col + vcol] : 0.0;
}
int matrix::set (short vrow,short vcol,double val) {
        if (vrow >= 0 && vrow < row && vcol >= 0 && vcol < col ) {
                elems[vrow * col + vcol] = val;
                return 0;
        } else {
                return 1;
        }
}
matrix operator + (matrix m1,matrix m2) {
        matrix m3(m1.row,m1.col);
        if (m1.row != m2.row || m1.col != m2.col ) return m3;
        for( int i = 0 ; i < m1.row  ; i++ ) {
                for ( int j = 0 ; j < m1.col ; j++ )
                        m3.set(i,j,m1(i,j) + m2(i,j));
        }
        return m3;
}
matrix operator - (matrix m1,matrix m2) {
        matrix m(m1.row,m1.col);
        if (m1.row != m2.row || m1.col != m2.col ) return m;
        for( int i = 0 ; i < m1.row  ; i++ ) {
                for ( int j = 0 ; j < m1.col ; j++ ) {
                        cout << i << "," << j << "," << m1(i,j) << "," << m2(i,j) << "\n";
                        m.set(i,j,m1(i,j) - m2(i,j));
                }
        }
        return m;
}
matrix operator * (matrix m1,matrix m2) {
        matrix m3(m1.row,m2.col);
        if ( m1.col != m2.row ) return m3;
        for ( int i = 0 ; i < m1.row ; i++ ) {
                for ( int j = 0 ; j < m2.col; j++ ) {
                        double value = 0 ;
                        for ( int k = 0 ; k < m1.col ; k++ )
                                value += m1(i,k) * m2(k,j) ;
                        m3.set(i , j , value);
                }
        }
        return m3;
}
int main() {

        matrix m1(3,4),m2(3,4),m3(2,3),m4(3,4),m5(2,4),m6(3,4);
        m1.set(0,0,1);
        m1.set(0,1,2);
        m1.set(0,2,3);
        m1.set(0,3,4);
        m1.set(1,0,5);
        m1.set(1,1,6);
        m1.set(1,2,7);
        m1.set(1,3,;
        m1.set(2,0,9);
        m1.set(2,1,10);
        m1.set(2,2,11);
        m1.set(2,3,12);
        m2.set(0,0,1);
        m2.set(0,1,2);
        m2.set(0,2,3);
        m2.set(0,3,4);
        m2.set(1,0,5);
        m2.set(1,1,6);
        m2.set(1,2,7);
        m2.set(1,3,;
        m2.set(2,0,9);
        m2.set(2,1,10);
        m2.set(2,2,11);
        m2.set(2,3,12);
        m3.set(0,0,1);
        m3.set(0,1,2);
        m3.set(0,2,3);
        m3.set(1,0,4);
        m3.set(1,1,5);
        m3.set(1,2,6);
        m3.print();
        cout << "----------------\n";
        m1.print();
        cout << "----------------\n";
        m2.print();
        cout << "----------------\n";
        m4 = m1 + m2;
        m4.print();
        cout << "----------------\n";
        m6 = m1 - m2;
        m6.print();
        m5 = m3 * m1;
        m5.print();
}

论坛徽章:
0
3 [报告]
发表于 2008-05-22 18:21 |只看该作者
大家帮我分析一下为啥执行过m4 = m1 + m2;后
m1.elems[0]的值会变为:
6.242062818703445e-308

谢谢!

论坛徽章:
0
4 [报告]
发表于 2008-05-22 19:47 |只看该作者

回复 #1 welcome008 的帖子

返回临时对象
so...

论坛徽章:
0
5 [报告]
发表于 2008-05-23 09:28 |只看该作者
原帖由 wantjutju 于 2008-5-22 19:47 发表
返回临时对象
so...



能否详细点?
谢谢!

论坛徽章:
0
6 [报告]
发表于 2008-05-23 10:50 |只看该作者
谁再给仔细解释下,谢谢!

论坛徽章:
0
7 [报告]
发表于 2008-05-23 17:15 |只看该作者
使用了拷贝构造函数,解决修改elems[0]的问题,可是为何仍然报错呢?

*** glibc detected *** ./a.out: double free or corruption (out): 0x084602f8 ***
======= Backtrace: =========
/lib/libc.so.6[0x17aac1]
/lib/libc.so.6(cfree+0x90)[0x17e0f0]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x24e06f1]
./a.out(__gxx_personality_v0+0x31b)[0x80488e7]
./a.out[0x804957b]
/lib/libc.so.6(__libc_start_main+0xe0)[0x127390]
./a.out(__gxx_personality_v0+0x45)[0x8048611]
======= Memory map: ========
00110000-00111000 r-xp 00110000 00:00 0          [vdso]
00111000-00264000 r-xp 00000000 fd:00 1067801    /lib/libc-2.7.so
00264000-00266000 r-xp 00153000 fd:00 1067801    /lib/libc-2.7.so
00266000-00267000 rwxp 00155000 fd:00 1067801    /lib/libc-2.7.so
00267000-0026a000 rwxp 00267000 00:00 0
00296000-002b1000 r-xp 00000000 fd:00 1067800    /lib/ld-2.7.so
002b1000-002b2000 r-xp 0001a000 fd:00 1067800    /lib/ld-2.7.so
002b2000-002b3000 rwxp 0001b000 fd:00 1067800    /lib/ld-2.7.so
00d68000-00d8f000 r-xp 00000000 fd:00 1067805    /lib/libm-2.7.so
00d8f000-00d90000 r-xp 00026000 fd:00 1067805    /lib/libm-2.7.so
00d90000-00d91000 rwxp 00027000 fd:00 1067805    /lib/libm-2.7.so
0242d000-0250d000 r-xp 00000000 fd:00 227099     /usr/lib/libstdc++.so.6.0.8
0250d000-02511000 r-xp 000df000 fd:00 227099     /usr/lib/libstdc++.so.6.0.8
02511000-02512000 rwxp 000e3000 fd:00 227099     /usr/lib/libstdc++.so.6.0.8
02512000-02518000 rwxp 02512000 00:00 0
07fe6000-07ff1000 r-xp 00000000 fd:00 1067812    /lib/libgcc_s-4.1.2-20070925.so.1
07ff1000-07ff2000 rwxp 0000a000 fd:00 1067812    /lib/libgcc_s-4.1.2-20070925.so.1
08048000-0804a000 r-xp 00000000 fd:00 1202293    /home/liuhy/c/9/a.out
0804a000-0804b000 rw-p 00001000 fd:00 1202293    /home/liuhy/c/9/a.out
08460000-08481000 rw-p 08460000 00:00 0
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7fd8000-b7fda000 rw-p b7fd8000 00:00 0
b7feb000-b7fec000 rw-p b7feb000 00:00 0
bff3a000-bff4f000 rw-p bffea000 00:00 0          [stack]
已放弃

论坛徽章:
0
8 [报告]
发表于 2008-05-24 14:59 |只看该作者
原帖由 welcome008 于 2008-5-23 17:15 发表
使用了拷贝构造函数,解决修改elems[0]的问题,可是为何仍然报错呢?

*** glibc detected *** ./a.out: double free or corruption (out): 0x084602f8 ***
======= Backtrace: =========
/lib/libc.so.6[0 ...



是很难呢?还是太简单大家不愿意回答?
我想应该不是很难吧?

论坛徽章:
0
9 [报告]
发表于 2008-05-24 15:02 |只看该作者
我猜是老师布置的作业吧,最好的办法是找同学交流。

论坛徽章:
0
10 [报告]
发表于 2008-05-24 17:13 |只看该作者
呵呵,不是作业,只是我看到书上的例子,比葫芦画瓢,写的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP