Segmentation fault implementing matrix class c++

分割故障矩阵类的C++实现

Tags: c++
标签: c++

问题 (Question)

I wanted to implement the strassen's algorithm and I though to implement a matrix class. However I get a segmentation fault with the following code:

class Matrix {
    public:
        vector < vector <int> > m;
        int r;
        int c;
        Matrix() {;}
        Matrix(int _r, int _c) {
            r = _r;
            c = _c;
            m.resize(r);
            for (int i = 0; i < r; i++) {
                m[i].resize(c);
            }
            for(int i =0; i < r; i++){
                for(int j=0; j< c; j++){
                    m[i][j] = 0;
                }
            }
        }
        friend ostream& operator<<(ostream &out, Matrix &A) {
            for(int i =0; i<A.r; i++){
                out << endl;
                for(int j=0; j<A.c; j++){
                    out << A.m[i][j] << "\t";
                }
            }
            out<< endl;
            return out;
        }

        Matrix(const Matrix &A) {
            c = A.c; 
            r = A.r;
            m.resize(r);
            for (int i = 0; i < r; i++) {
                m[i].resize(c);
            }
            for(int i =0; i<r; i++){
                for(int j=0; j<c; j++){
                    m[i][j] =  A.m[i][j];
                }
            }
        }

        Matrix& operator-= (Matrix &A) {
            assert(A.r == r);
            assert(A.c == c);
            for(int i =0; i<r; i++){
                for(int j=0; j<c; j++){
                    m[i][j] -= A.m[i][j];
                }
            }
            return *this;
        }
        Matrix& operator- (Matrix &A) {
            Matrix C(*this);
            return C-=A;
        }
        Matrix& operator+= (Matrix &A) {
            assert(A.r == r);
            assert(A.c == c);
            for(int i =0; i<r; i++){
                for(int j=0; j<c; j++){
                    m[i][j] += A.m[i][j];
                }
            }
            return *this;
        }
        Matrix& operator+ (Matrix &A) {
            Matrix C (*this);
            (C)+=A;
            return C;
        }


        Matrix getBlock(int sR, int eR, int sC, int eC) {
            assert(sR > eR);
            assert(sC > eC);
            Matrix C(eR-sR, eC-sC);
            for(int i = 0; i < C.r; i++) {
                for(int j=0; j < C.c; j++) {
                    C.m[i][j] = m[sR+i][sC+j];
                }
            }
            return C;
        }

        friend void swap(Matrix& first, Matrix& second) {
            using std::swap; 
            swap(first.r, second.r); 
            swap(first.c, second.c); 
            swap(first.m, second.m);
        }

        Matrix& operator=(Matrix other){
            return *this;
        }

        friend Matrix& operator*(const Matrix& A, const Matrix &B) {
            assert(A.r == B.c);
            Matrix C(A.r, B.c);
            for(int i =0; i<C.r; i++){
                for(int j=0; j<C.c; j++){
                    for(int k = 0; k < A.r; k++) {
                        C.m[i][j] += A.m[i][k] * B.m[k][j];
                    }
                }
            }
            return C;
        }

};

int main (void) 
{
    Matrix A(2,2), B(2,2);
    A.m[0][0] = 1;  A.m[0][1] = 2;
    A.m[1][0] = 3;  A.m[1][1] = 4;
    B.m[0][0] = 1;  B.m[0][1] = 2;
    B.m[1][0] = 3;  B.m[1][1] = 4;
    Matrix C(2,2);
    C =A+B;
    cout << C << endl;
    return 0;

}

If I try A+=B; it works... I do not understand what it is the difference with A+B. I tried to print C before returning from

Matrix& operator+ (Matrix &
    Matrix C (*this);
    (C)+=A;
    return C;
} 

And it is correct. When the code hit the return, my program crashes. I would like to understand what I am doing wrong. Thanks a lot. Davide

我想实现Strassen算法和我虽然实现矩阵类。但是我得到的分割故障与下面的代码:

class Matrix {
    public:
        vector < vector <int> > m;
        int r;
        int c;
        Matrix() {;}
        Matrix(int _r, int _c) {
            r = _r;
            c = _c;
            m.resize(r);
            for (int i = 0; i < r; i++) {
                m[i].resize(c);
            }
            for(int i =0; i < r; i++){
                for(int j=0; j< c; j++){
                    m[i][j] = 0;
                }
            }
        }
        friend ostream& operator<<(ostream &out, Matrix &A) {
            for(int i =0; i<A.r; i++){
                out << endl;
                for(int j=0; j<A.c; j++){
                    out << A.m[i][j] << "\t";
                }
            }
            out<< endl;
            return out;
        }

        Matrix(const Matrix &A) {
            c = A.c; 
            r = A.r;
            m.resize(r);
            for (int i = 0; i < r; i++) {
                m[i].resize(c);
            }
            for(int i =0; i<r; i++){
                for(int j=0; j<c; j++){
                    m[i][j] =  A.m[i][j];
                }
            }
        }

        Matrix& operator-= (Matrix &A) {
            assert(A.r == r);
            assert(A.c == c);
            for(int i =0; i<r; i++){
                for(int j=0; j<c; j++){
                    m[i][j] -= A.m[i][j];
                }
            }
            return *this;
        }
        Matrix& operator- (Matrix &A) {
            Matrix C(*this);
            return C-=A;
        }
        Matrix& operator+= (Matrix &A) {
            assert(A.r == r);
            assert(A.c == c);
            for(int i =0; i<r; i++){
                for(int j=0; j<c; j++){
                    m[i][j] += A.m[i][j];
                }
            }
            return *this;
        }
        Matrix& operator+ (Matrix &A) {
            Matrix C (*this);
            (C)+=A;
            return C;
        }


        Matrix getBlock(int sR, int eR, int sC, int eC) {
            assert(sR > eR);
            assert(sC > eC);
            Matrix C(eR-sR, eC-sC);
            for(int i = 0; i < C.r; i++) {
                for(int j=0; j < C.c; j++) {
                    C.m[i][j] = m[sR+i][sC+j];
                }
            }
            return C;
        }

        friend void swap(Matrix& first, Matrix& second) {
            using std::swap; 
            swap(first.r, second.r); 
            swap(first.c, second.c); 
            swap(first.m, second.m);
        }

        Matrix& operator=(Matrix other){
            return *this;
        }

        friend Matrix& operator*(const Matrix& A, const Matrix &B) {
            assert(A.r == B.c);
            Matrix C(A.r, B.c);
            for(int i =0; i<C.r; i++){
                for(int j=0; j<C.c; j++){
                    for(int k = 0; k < A.r; k++) {
                        C.m[i][j] += A.m[i][k] * B.m[k][j];
                    }
                }
            }
            return C;
        }

};

int main (void) 
{
    Matrix A(2,2), B(2,2);
    A.m[0][0] = 1;  A.m[0][1] = 2;
    A.m[1][0] = 3;  A.m[1][1] = 4;
    B.m[0][0] = 1;  B.m[0][1] = 2;
    B.m[1][0] = 3;  B.m[1][1] = 4;
    Matrix C(2,2);
    C =A+B;
    cout << C << endl;
    return 0;

}

如果我试试+ = B;它的作品…我不明白什么是差异与+我想打印c返回前

Matrix& operator+ (Matrix &
    Matrix C (*this);
    (C)+=A;
    return C;
} 

这是正确的。当代码打回来,我的程序崩溃。我想了解我在做什么错。谢谢。

最佳答案 (Best Answer)

In operator+ you are returning a reference to a locally constructed object. The object will be destroyed at the exit of the function, so you end up with a dangling reference. Same story with operator*. Here is a nice tutorial about operator overloading

http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html

进入operator+你是返回一个引用到一个局部构造的对象。对象将在函数退出了,所以你结束了一个晃来晃去的参考。同样的故事operator*。这是关于运算符重载的一个很好的教程

http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html

答案 (Answer) 2

You can't use a local variable as an l-value return value.

Matrix& operator=(Matrix && other){
            this->m = other.m;
            return *this;
        }

Matrix operator+ (Matrix &A) {
            Matrix C (*this);
            (C)+=A;
            return std::move(C);
        }

This would fix this problem.

你不能使用局部变量是左值的返回值。

Matrix& operator=(Matrix && other){
            this->m = other.m;
            return *this;
        }

Matrix operator+ (Matrix &A) {
            Matrix C (*this);
            (C)+=A;
            return std::move(C);
        }

这将解决这个问题。

答案 (Answer) 3

The problem , as others have pointed out, is that you return a reference to a local variable, which is destroyed when that function exits.

The usual way to implement operator+ is as a non-member function:

Matrix operator+(Matrix A, Matrix const &B)
{
    return A += B;
}

This approach is better than the member function in that it allows conversions to occur on the left-hand operand.

Your operator- and operator* have the same issue.

问题,为其他人所指出的,是你返回局部变量的引用,它破坏了当函数退出。

执行通常的方式operator+作为一个非成员函数:

Matrix operator+(Matrix A, Matrix const &B)
{
    return A += B;
}

这种方法比的成员函数,它允许转换到左操作数出现。

你的operator-operator*有同样的问题。

本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:http://stackoverflow.com/questions/23451039