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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Вадим Ром
0 / 0 / 1
Регистрация: 11.07.2014
Сообщений: 8
#1

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

11.07.2014, 15:36. Просмотров 280. Ответов 11
Метки нет (Все метки)

Подскажите пожалуйста! Написал класс матриц с перегруженными операторами
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++
C++ Деструктор не вызывается
почему виртуальный деструктор вызывается дважды? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ilot
Модератор
Эксперт С++
1780 / 1155 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 15:47     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #2
Как минимум оператор Matrix3d operator+(const Matrix3d& m) должен быть friend функцией
Renji
1696 / 1129 / 270
Регистрация: 05.06.2014
Сообщений: 3,280
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
Модератор
Эксперт С++
1780 / 1155 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 16:00     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #4
del..
Renji
1696 / 1129 / 270
Регистрация: 05.06.2014
Сообщений: 3,280
11.07.2014, 16:08     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #5
Зачем он тут нужен?
Затем, что return newMatrix копирует newMatrix из стека operator+ в память вызвавшей функции. И получаются два объекта владеющие одним newMatrix.matrix. Потом эти объекты пытаются свой указатель почистить и стукаются лбами.
aLarman
640 / 561 / 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
1696 / 1129 / 270
Регистрация: 05.06.2014
Сообщений: 3,280
11.07.2014, 16:18     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #8
не надо возвращать локальную переменную, ни к чему это,
Ну и как по вашему operator+ должен вернуть результат? Глобальную переменную-приемник в него передать не получится.
да и деструктор для всех локальных переменных при выходе из функций вызывается.
Вот для этого и существует перемещающий конструктор.
Ilot
Модератор
Эксперт С++
1780 / 1155 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 16:19     Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. #9
Цитата Сообщение от Renji Посмотреть сообщение
Затем, что return newMatrix копирует newMatrix из стека operator+ в память вызвавшей функции. И получаются два объекта владеющие одним newMatrix.matrix. Потом эти объекты пытаются свой указатель почистить и стукаются лбами.
Да туплю.
Цитата Сообщение от aLarman Посмотреть сообщение
чеэто?
Солтер стр. 498
zss
Модератор
Эксперт С++
 Аватар для zss
6110 / 5713 / 1849
Регистрация: 18.12.2011
Сообщений: 14,590
Завершенные тесты: 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++ Вызывается ли деструктор в данной программе?
C++ Почему не вызывается деструктор?
Не вызывается деструктор структуры C++
C++ Почему вызывается деструктор?

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

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

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