Reputation: 36
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
Upvotes: 1
Views: 105
Reputation: 141544
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.
Upvotes: 0
Reputation: 1366
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.
Upvotes: 0
Reputation: 56547
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
Upvotes: 3