Форум программистов, компьютерный форум CyberForum.ru

Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. - C++

Восстановить пароль Регистрация
 
Вадим Ром
0 / 0 / 1
Регистрация: 11.07.2014
Сообщений: 8
11.07.2014, 15:36     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #1
Подскажите пожалуйста! Написал класс матриц с перегруженными операторами
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
class Matrix3d{
public:
  double** matrix;
  Matrix3d();
  Matrix3d(double m11,double m12,double m13,double m21,double m22,double m23,double m31,double m32,double m33);
  ~Matrix3d();
  Matrix3d* Inverse();
  double determinant();
  double getvalue(int i,int j);
  void setvalue(int i,int j, double value);
  Matrix3d& operator=(const Matrix3d& matr);
  Vector3d operator*(const Vector3d& v);
  Matrix3d operator+(const Matrix3d& m);
  Matrix3d& operator+=(const Matrix3d& matr);
  Matrix3d& operator-=(const Matrix3d& matr);
  static Matrix3d* createBasisByOneVector(const Vector3d& v);
};
 
#include "math.h"
#include "stdio.h"
 
#include "matrix3d.h"
#include "vector3d.h"
#include "constants.h"
 
Matrix3d::Matrix3d(){
  int i,j;
  matrix=new double* [3];
  for(i=0;i<3;++i){
    matrix[i]=new double [3];
    for (j=0;j<3;++j){
      if (i==j){
        matrix[i][j]=1;
      }else{
        matrix[i][j]=0;
      }
    }
  }
}
 
Matrix3d::  Matrix3d(double m11,double m12,double m13,double m21,double m22,double m23,double m31,double m32,double m33){
    matrix=new double* [3];
    for(int i=0;i<3;++i){
        matrix[i]=new double [3];
    }
    matrix[0][0] = m11;
    matrix[0][1] = m12;
    matrix[0][2] = m13;
    matrix[1][0] = m21;
    matrix[1][1] = m22;
    matrix[1][2] = m23;
    matrix[2][0] = m31;
    matrix[2][1] = m32;
    matrix[2][2] = m33;
}
 
Matrix3d::~Matrix3d(){
  int i;
  for(i=0;i<3;++i){
    delete[] matrix[i];
  }
  delete[] matrix;
}
Matrix3d* Matrix3d::Inverse(){
  Matrix3d* inv = new Matrix3d();
  double det;
  det=matrix[0][0]*(matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1])-matrix[0][1]*(matrix[1][0]*matrix[2][2]-matrix[1][2]*matrix[2][0])+matrix[0][2]*(matrix[1][0]*matrix[2][1]-matrix[1][1]*matrix[2][0]);
  if (fabs(det) > epsilon){
    inv->matrix[0][0]=(1/det)*(matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1]);
    inv->matrix[0][1]=-(1/det)*(matrix[0][1]*matrix[2][2]-matrix[0][2]*matrix[2][1]);
    inv->matrix[0][2]=(1/det)*(matrix[0][1]*matrix[1][2]-matrix[0][2]*matrix[1][1]);
    inv->matrix[1][0]=-(1/det)*(matrix[1][0]*matrix[2][2]-matrix[1][2]*matrix[2][0]);
    inv->matrix[1][1]=(1/det)*(matrix[0][0]*matrix[2][2]-matrix[0][2]*matrix[2][0]);
    inv->matrix[1][2]=-(1/det)*(matrix[0][0]*matrix[1][2]-matrix[1][0]*matrix[0][2]);
    inv->matrix[2][0]=(1/det)*(matrix[1][0]*matrix[2][1]-matrix[1][1]*matrix[2][0]);
    inv->matrix[2][1]=-(1/det)*(matrix[0][0]*matrix[2][1]-matrix[0][1]*matrix[2][0]);
    inv->matrix[2][2]=(1/det)*(matrix[0][0]*matrix[1][1]-matrix[1][0]*matrix[0][1]);
  } else {
      printf("determinant = 0\n");
  }
  return inv;
}
double Matrix3d::determinant(){
  double temp;
  temp=matrix[0][0]*(matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1])-matrix[0][1]*(matrix[1][0]*matrix[2][2]-matrix[1][2]*matrix[2][0])+matrix[0][2]*(matrix[0][1]*matrix[2][1]-matrix[1][1]*matrix[0][2]);
  return temp;
}
double Matrix3d::getvalue(int i,int j){
  return matrix[i][j];
}
void Matrix3d::setvalue(int i,int j, double value){
  matrix[i][j]=value;
}
Matrix3d& Matrix3d::operator=(const Matrix3d& matr){
  int i;
  int j;
  for(i=0;i<3;++i){
    for(j=0;j<3;++j){
        matrix[i][j]=matr.matrix[i][j];
    }
  }
  return *this;
}
 
Vector3d Matrix3d::operator*(const Vector3d& v){
    double x = matrix[0][0]*v.x + matrix[0][1]*v.y + matrix[0][2]*v.z;
    double y = matrix[1][0]*v.x + matrix[1][1]*v.y + matrix[1][2]*v.z;
    double z = matrix[2][0]*v.x + matrix[2][1]*v.y + matrix[2][2]*v.z;
    return Vector3d(x,y,z);
}
 
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
    int i;
    int j;
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            newMatrix.matrix[i][j]=matr.matrix[i][j] + matrix[i][j];
        }
    }
    return newMatrix;
}
 
Matrix3d& Matrix3d::operator+=(const Matrix3d& matr){
    int i;
    int j;
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            matrix[i][j] = matr.matrix[i][j] + matrix[i][j];
        }
    }
    return *this;
}
 
Matrix3d& Matrix3d::operator-=(const Matrix3d& matr){
    int i;
    int j;
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            matrix[i][j] = matrix[i][j] - matr.matrix[i][j];
        }
    }
    return *this;
}
 
Matrix3d* Matrix3d::createBasisByOneVector(const Vector3d& v){
    if ((v.z*v.z + v.y*v.y + v.x*v.x) < epsilon){
        return new Matrix3d(1,0,0,0,1,0,0,0,1);
    }
    double theta = acos(v.z/sqrt(v.z*v.z + v.y*v.y + v.x*v.x));
    double phi = atan2(v.y,v.x);
    return new Matrix3d(sin(phi),cos(theta)*cos(phi),sin(theta)*cos(phi),-cos(phi),cos(theta)*sin(phi),sin(theta)*sin(phi),0,-sin(theta),cos(theta));
}
Далее в основной программе пишу

C++
1
2
3
4
5
    Matrix3d A;
    Matrix3d B;
    Matrix3d C;
 
    A = B+C;
В итоге деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. Что делать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2014, 15:36     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает.
Посмотрите здесь:

C++ Оператор присваивания и деструктор
Два раза вызывается деструктор C++
Когда вызывается деструктор класса? C++
Не вызывается деструктор C++
C++ Деструктор не вызывается
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 15:47     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #2
Как минимум оператор Matrix3d operator+(const Matrix3d& m) должен быть friend функцией
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
11.07.2014, 15:51     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #3
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
...
    return newMatrix;
}
Копирующий( Matrix3d(const Matrix3d&src) )/перемещающий( Matrix3d(Matrix3d&&src) ) конструктор надо, иначе newMatrix корректно не вернется.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 16:00     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #4
del..
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
11.07.2014, 16:08     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #5
Зачем он тут нужен?
Затем, что return newMatrix копирует newMatrix из стека operator+ в память вызвавшей функции. И получаются два объекта владеющие одним newMatrix.matrix. Потом эти объекты пытаются свой указатель почистить и стукаются лбами.
aLarman
636 / 557 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
11.07.2014, 16:08     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #6
Цитата Сообщение от Ilot Посмотреть сообщение
должен быть friend функцией
чеэто?
olper
24 / 24 / 11
Регистрация: 02.12.2013
Сообщений: 75
11.07.2014, 16:16     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #7
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
  ...
    return newMatrix;
}
не надо возвращать локальную переменную, ни к чему это,
да и деструктор для всех локальных переменных при выходе из функций вызывается.
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
11.07.2014, 16:18     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #8
не надо возвращать локальную переменную, ни к чему это,
Ну и как по вашему operator+ должен вернуть результат? Глобальную переменную-приемник в него передать не получится.
да и деструктор для всех локальных переменных при выходе из функций вызывается.
Вот для этого и существует перемещающий конструктор.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 16:19     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #9
Цитата Сообщение от Renji Посмотреть сообщение
Затем, что return newMatrix копирует newMatrix из стека operator+ в память вызвавшей функции. И получаются два объекта владеющие одним newMatrix.matrix. Потом эти объекты пытаются свой указатель почистить и стукаются лбами.
Да туплю.
Цитата Сообщение от aLarman Посмотреть сообщение
чеэто?
Солтер стр. 498
zss
Модератор
Эксперт С++
 Аватар для zss
5952 / 5557 / 1787
Регистрация: 18.12.2011
Сообщений: 14,204
Завершенные тесты: 1
11.07.2014, 16:28     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #10
Обратите внимание, что Вы забыли написать копиконструктор!
Думаю, именно поэтому и падает!
Вадим Ром
0 / 0 / 1
Регистрация: 11.07.2014
Сообщений: 8
11.07.2014, 16:52  [ТС]     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #11
Цитата Сообщение от Renji Посмотреть сообщение
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
...
    return newMatrix;
}
Копирующий( Matrix3d(const Matrix3d&src) )/перемещающий( Matrix3d(Matrix3d&&src) ) конструктор надо, иначе newMatrix корректно не вернется.
Спасибо большое, помогло!

Добавлено через 17 минут
Цитата Сообщение от Renji Посмотреть сообщение
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
...
    return newMatrix;
}
Копирующий( Matrix3d(const Matrix3d&src) )/перемещающий( Matrix3d(Matrix3d&&src) ) конструктор надо, иначе newMatrix корректно не вернется.
Спасибо, помогло
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2014, 16:56     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает.
Еще ссылки по теме:

Не вызывается деструктор C++
C++ При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
C++ Почему не вызывается деструктор?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
IrineK
Заблокирован
11.07.2014, 16:56     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #12
Правило трёх
Yandex
Объявления
11.07.2014, 16:56     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает.
Ответ Создать тему
Опции темы

Текущее время: 22:43. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru