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

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

Войти
Регистрация
Восстановить пароль
 
 
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
#1

Ошибка при работе с объектами - C++

30.09.2013, 23:37. Просмотров 499. Ответов 19
Метки нет (Все метки)

Доброго времени суток!
Я написал программу для работы с матрицами.
При умножении происходит следующее:
Matrix M3 = M1 * M2; // после этого M3 = M1.
Отладка показала, что возвращаемый из оператора * объект уничтожается, а затем копирующий конструктор копирует M1 в M3.

Помогите, пожалуйста, разобраться.

Объявление класса
Кликните здесь для просмотра всего текста
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
#pragma once
 
class Matrix
{
private:
    int** matrix; // указатель на двухмерный массив
    int rows, columns; // число строк и столбцов
    bool Init; // инициализирована ли матрица
 
public:
    Matrix (int sizeX, int sizeY, int** table = nullptr);
    Matrix (const Matrix& obj); // копирующий конструктор
    ~Matrix ();
 
    int Transposition (); //транспонирование
    double Determinant (); // поиск определителя
 
    int Print (); // вывод на экран
    bool Read (char filename []); // чтение матрицы из файла
    bool Load (char filename []); // сохранение в файл
 
    Matrix& operator= (const Matrix& obj); // оператор присваивания
 
    Matrix operator*= (Matrix& obj);
    friend Matrix operator* (Matrix& obj1, Matrix& obj2);
 
};


Конструкторы
Кликните здесь для просмотра всего текста
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
Matrix :: Matrix (int SizeX, int SizeY, int** table): rows (SizeY), columns (SizeX), Init (false)
{
    if (table == nullptr) // если нет инициализатора матрицы
    {
        // выделение памяти под двухмерный массив
        matrix = new int* [SizeY];
        for (int i = 0; i < SizeY; i ++)
            *(matrix + i) = new int [SizeX];
    }
 
    else
    {
        matrix = table;
        for (int i = 0; i < SizeY; i ++)
            *(matrix + i) = *(table + i);
    }
 
 
}
 
Matrix :: Matrix (const Matrix& obj)
{
    // выделяем память
    this -> matrix = new int* [obj.rows];
    for (int i = 0; i < obj.rows; i ++)
        *(matrix + i) = new int [obj.columns];
 
    this -> rows = obj.rows;
    this -> columns = obj.columns;
 
    // копируем значения
    for (int i = 0; i < this -> rows; i ++)
        for (int j = 0; j < this -> columns; j ++)
            this -> matrix [i] [j] = obj.matrix [i] [j];
}


Деструктор
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
Matrix :: ~Matrix ()
{
    for (int i = 0; i < this -> rows; i ++)
        delete [] matrix [i];
 
    delete [] matrix;
 
    delete [] combination;
}


Оператор присваивания
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Matrix& Matrix :: operator= (const Matrix& obj)
{
    if (this != &obj) // если не самоприсваивание
    {
        //if (this -> rows != obj.rows || this -> columns != obj.columns)
        //  throw BadSize ();
 
        // копируем значения
        for (int i = 0; i < this -> rows; i ++)
            for (int j = 0; j < this -> columns; j ++)
                this -> matrix [i] [j] = obj.matrix [i] [j];
 
    }
 
    return *this;
}


Оператор умножения
Кликните здесь для просмотра всего текста
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
Matrix Matrix :: operator*= (Matrix& obj)
{
    //if (!this -> Init || !obj.Init)
    //  throw NotInit ();
 
    //if (this -> columns != obj.rows)
        //throw BadSize ();
 
    // выделяем память под новую матрицу
    int** table = new int* [this -> rows];
    for (int i = 0; i < this -> rows; i ++)
        *(table + i) = new int [obj.columns];
 
    // следующий страшный алгоритм умножает строки на столбцы
    int a;
    int x = -1, y = -1;
 
    for (int k = 0; k < this -> rows; k ++)
    {
        y ++;
        x = -1;
        for (int i = 0; i < obj.rows; i ++)
        {
            a = 0;
            x++;
            for (int j = 0; j < this -> columns; j ++)
                a += this -> matrix [k] [j] * obj.matrix [j] [i];
 
            table [y] [x] = a;
        }
    }
 
    return Matrix (x + 1, y + 1, table);
}


И, на всякий, случай, main
Кликните здесь для просмотра всего текста
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
#include <iostream>
using std :: cout;
using std :: cin;
 
#include "Class_Matrix.h"
 
#include <Windows.h>
 
int main ()
{
    setlocale (LC_ALL, "Rus");
 
    Matrix M1 (2, 2);
    M1.Read ("1.txt");
    
    Matrix M2 (2,2);
    M2.Read ("2.txt");
 
    Matrix M3 = M1 * M2;
    M3.Load ("3.txt");
 
    system ("pause");
    return 0;
}


P.s. в Read и Load матрицы считываются из файла и, соответственно, записываются.

Буду рад любой помощи и замечаниям по коду. Заранее спасибо)
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2013, 23:37
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибка при работе с объектами (C++):

Ошибка при компиляции. Как правильно создавать класс с объектами от другого класса? - C++
Есть класс Car. У него есть двигатель(class Engine) и переменная скорость(speed), которая зависит от мощности(power). power- переменная...

Не является внутренней или внешней командой - ошибка не при компиляции а при работе программы - C++
В VS скомпилировал код #include &lt;iostream&gt; using namespace std; int main() { int a; cout&lt;&lt;&quot;Hallo&quot;; cin&gt;&gt;a; cout&lt;&lt;a; ...

Ошибка при работе со строками - C++
Добрый день! Я писал программу, которая после приставки под вставляет символ 'Ъ'. Я её написал, но она работает не корректно. Вот примеры...

Ошибка при работе с графикой - C++
Написал свою первую програмку на графику: Код: #include &lt;graphics.h&gt; #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;stdlib.h&gt; ...

Ошибка при работе с ifstream - C++
есть вот такой код и я точно знаю что у меня проблема вот тут: std::ifstream i1(&quot;s1&quot;), i2(&quot;s2&quot;); помогите исправить. #include &lt;conio.h&gt; ...

Ошибка при работе с памятью - C++
Если ввести например 6, 0, чтобы выбросить исключение. То по завершение программы выскакивает ошибка. В чём может быть дело? Так что то про...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.09.2013, 23:39 #2
Цитата Сообщение от Ryabchik Посмотреть сообщение
Ошибка при работе с объектами
Какая?
0
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
30.09.2013, 23:44  [ТС] #3
Вот
Цитата Сообщение от Ryabchik Посмотреть сообщение
При умножении происходит следующее:
Matrix M3 = M1 * M2; // после этого M3 = M1.
Отладка показала, что возвращаемый из оператора * объект уничтожается, а затем копирующий конструктор копирует M1 в M3.
0
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.10.2013, 00:17 #4
Цитата Сообщение от Ryabchik Посмотреть сообщение
Оператор умножения
Это оператор умножения?
Цитата Сообщение от Ryabchik Посмотреть сообщение
operator*=
0
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
01.10.2013, 00:52  [ТС] #5
Извиняюсь, забыл
C++
1
2
3
4
5
Matrix operator* (Matrix& obj1, Matrix& obj2)
{
       obj1 *= obj2;
       return obj1;
}
0
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.10.2013, 00:53 #6
Кликните здесь для просмотра всего текста
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
class Matrix
{
//private:
 public:   
    int** matrix; // указатель на двухмерный массив
    int rows, columns; // число строк и столбцов
    bool Init; // инициализирована ли матрица
 
 
    Matrix (int sizeX, int sizeY, int** table = nullptr);
    Matrix (const Matrix& obj); // копирующий конструктор
    ~Matrix ();
 
    int Transposition (); //транспонирование
    double Determinant (); // поиск определителя
 
    int Print (); // вывод на экран
    bool Read (char filename []); // чтение матрицы из файла
    bool Load (char filename []); // сохранение в файл
 
    Matrix& operator= (const Matrix& obj); // оператор присваивания
 
    const Matrix operator*(Matrix& obj);
    //friend Matrix operator* (Matrix& obj1, Matrix& obj2);
 
};
 
Matrix :: Matrix (int SizeX, int SizeY, int** table): rows (SizeY), columns (SizeX), Init (false)
{
    if (table == nullptr) // если нет инициализатора матрицы
    {
        // выделение памяти под двухмерный массив
        matrix = new int* [SizeY];
        for (int i = 0; i < SizeY; i ++)
            *(matrix + i) = new int [SizeX];
    }
 
    else
    {
        matrix = table;
        for (int i = 0; i < SizeY; i ++)
            *(matrix + i) = *(table + i);
    }
 
 
}
 
Matrix :: Matrix (const Matrix& obj)
{
    // выделяем память
    this -> matrix = new int* [obj.rows];
    for (int i = 0; i < obj.rows; i ++)
        *(matrix + i) = new int [obj.columns];
 
    this -> rows = obj.rows;
    this -> columns = obj.columns;
 
    // копируем значения
    for (int i = 0; i < this -> rows; i ++)
        for (int j = 0; j < this -> columns; j ++)
            this -> matrix [i] [j] = obj.matrix [i] [j];
}
 
Matrix :: ~Matrix ()
{
    for (int i = 0; i < this -> rows; i ++)
        delete [] matrix [i];
 
    delete [] matrix;
 
    //delete [] combination;
}
 
Matrix& Matrix :: operator= (const Matrix& obj)
{
    if (this != &obj) // если не самоприсваивание
    {
        //if (this -> rows != obj.rows || this -> columns != obj.columns)
        //  throw BadSize ();
 
        // копируем значения
        for (int i = 0; i < this -> rows; i ++)
            for (int j = 0; j < this -> columns; j ++)
                this -> matrix [i] [j] = obj.matrix [i] [j];
 
    }
 
    return *this;
}
 
const Matrix Matrix :: operator*(Matrix& obj)
{
    //if (!this -> Init || !obj.Init)
    //  throw NotInit ();
 
    //if (this -> columns != obj.rows)
        //throw BadSize ();
 
    // выделяем память под новую матрицу
    int** table = new int* [this -> rows];
    for (int i = 0; i < this -> rows; i ++)
        *(table + i) = new int [obj.columns];
 
    // следующий страшный алгоритм умножает строки на столбцы
    int a;
    int x = -1, y = -1;
 
    for (int k = 0; k < this -> rows; k ++)
    {
        y ++;
        x = -1;
        for (int i = 0; i < obj.rows; i ++)
        {
            a = 0;
            x++;
            for (int j = 0; j < this -> columns; j ++)
                a += this -> matrix [k] [j] * obj.matrix [j] [i];
 
            table [y] [x] = a;
        }
    }
 
    return Matrix (x + 1, y + 1, table);
}
 
#include <iostream>
using std :: cout;
using std :: cin;
using std :: endl; 
//#include "Class_Matrix.h"
 
#include <Windows.h>
 
int main ()
{
    setlocale (LC_ALL, "Rus");
 
    Matrix M1 (2, 2);
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 2; ++j)
            M1.matrix[i][j] = j + 1;
 
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2; ++j)
           cout << M1.matrix[i][j] << ' ';
        cout << endl;
    }
    cout << endl;
   // M1.Read ("1.txt");
    
    Matrix M2 (2, 2);
     for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 2; ++j)
            M2.matrix[i][j] = j + 2;
 
     for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2; ++j)
           cout << M2.matrix[i][j] << ' ';
        cout << endl;
    }
    cout << endl;
     //M2.Read ("2.txt");
 
    Matrix M3 = M1 * M2;
 
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2; ++j)
           cout << M3.matrix[i][j] << ' ';
        cout << endl;
    }
 
    //M3.Load ("3.txt");
 
    system ("pause");
    return 0;
}
1
Миниатюры
Ошибка при работе с объектами  
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
01.10.2013, 01:02  [ТС] #7
Delete

Добавлено через 7 минут
alsav22, я не совсем понял, в чем разница. В моем коде объект, возвращаемый из *= должен копироваться в obj1 и только потом уничтожаться. А он сразу угичтожается. Почему?
0
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.10.2013, 01:04 #8
Кликните здесь для просмотра всего текста
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
class Matrix
{
//private:
 public:   
    int** matrix; // указатель на двухмерный массив
    int rows, columns; // число строк и столбцов
    bool Init; // инициализирована ли матрица
 
 
    Matrix (int sizeX, int sizeY, int** table = nullptr);
    Matrix (const Matrix& obj); // копирующий конструктор
    ~Matrix ();
 
    int Transposition (); //транспонирование
    double Determinant (); // поиск определителя
 
    int Print (); // вывод на экран
    bool Read (char filename []); // чтение матрицы из файла
    bool Load (char filename []); // сохранение в файл
 
    Matrix& operator= (const Matrix& obj); // оператор присваивания
 
    const Matrix operator*(Matrix& obj);
    friend Matrix& operator*= (const Matrix& obj1, const Matrix& obj2);
 
};
 
Matrix :: Matrix (int SizeX, int SizeY, int** table): rows (SizeY), columns (SizeX), Init (false)
{
    if (table == nullptr) // если нет инициализатора матрицы
    {
        // выделение памяти под двухмерный массив
        matrix = new int* [SizeY];
        for (int i = 0; i < SizeY; i ++)
            *(matrix + i) = new int [SizeX];
    }
 
    else
    {
        matrix = table;
        for (int i = 0; i < SizeY; i ++)
            *(matrix + i) = *(table + i);
    }
 
 
}
 
Matrix :: Matrix (const Matrix& obj)
{
    // выделяем память
    this -> matrix = new int* [obj.rows];
    for (int i = 0; i < obj.rows; i ++)
        *(matrix + i) = new int [obj.columns];
 
    this -> rows = obj.rows;
    this -> columns = obj.columns;
 
    // копируем значения
    for (int i = 0; i < this -> rows; i ++)
        for (int j = 0; j < this -> columns; j ++)
            this -> matrix [i] [j] = obj.matrix [i] [j];
}
 
Matrix :: ~Matrix ()
{
    for (int i = 0; i < this -> rows; i ++)
        delete [] matrix [i];
 
    delete [] matrix;
 
    //delete [] combination;
}
 
Matrix& Matrix :: operator= (const Matrix& obj)
{
    if (this != &obj) // если не самоприсваивание
    {
        //if (this -> rows != obj.rows || this -> columns != obj.columns)
        //  throw BadSize ();
 
        // копируем значения
        for (int i = 0; i < this -> rows; i ++)
            for (int j = 0; j < this -> columns; j ++)
                this -> matrix [i] [j] = obj.matrix [i] [j];
 
    }
 
    return *this;
}
 
const Matrix Matrix :: operator*(Matrix& obj)
{
    //if (!this -> Init || !obj.Init)
    //  throw NotInit ();
 
    //if (this -> columns != obj.rows)
        //throw BadSize ();
 
    // выделяем память под новую матрицу
    int** table = new int* [this -> rows];
    for (int i = 0; i < this -> rows; i ++)
        *(table + i) = new int [obj.columns];
 
    // следующий страшный алгоритм умножает строки на столбцы
    int a;
    int x = -1, y = -1;
 
    for (int k = 0; k < this -> rows; k ++)
    {
        y ++;
        x = -1;
        for (int i = 0; i < obj.rows; i ++)
        {
            a = 0;
            x++;
            for (int j = 0; j < this -> columns; j ++)
                a += this -> matrix [k] [j] * obj.matrix [j] [i];
 
            table [y] [x] = a;
        }
    }
 
    return Matrix (x + 1, y + 1, table);
}
 
Matrix& operator*= (Matrix& obj1, Matrix& obj2)
{
       obj1 = obj1 * obj2;
       return obj1;
}
 
#include <iostream>
using std :: cout;
using std :: cin;
using std :: endl; 
//#include "Class_Matrix.h"
 
#include <Windows.h>
 
int main ()
{
    setlocale (LC_ALL, "Rus");
 
    Matrix M1 (2, 2);
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 2; ++j)
            M1.matrix[i][j] = j + 1;
 
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2; ++j)
           cout << M1.matrix[i][j] << ' ';
        cout << endl;
    }
    cout << endl;
   // M1.Read ("1.txt");
    
    Matrix M2 (2, 2);
     for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 2; ++j)
            M2.matrix[i][j] = j + 2;
 
     for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2; ++j)
           cout << M2.matrix[i][j] << ' ';
        cout << endl;
    }
    cout << endl;
     //M2.Read ("2.txt");
 
    Matrix M3 = M1 * M2;
 
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2; ++j)
           cout << M3.matrix[i][j] << ' ';
        cout << endl;
    }
 
    //M3.Load ("3.txt");
 
    system ("pause");
    return 0;
}
1
Миниатюры
Ошибка при работе с объектами  
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.10.2013, 01:05 #9
Цитата Сообщение от Ryabchik Посмотреть сообщение
alsav22, я не совсем понял, в чем разница.
Код правильный результат выводит?
0
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
01.10.2013, 12:43  [ТС] #10
alsav22, вечером попробую. А что изменилось, кроме того, что operator* стал функцией-членом?
0
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.10.2013, 17:58 #11
Цитата Сообщение от Ryabchik Посмотреть сообщение
А что изменилось, кроме того, что operator* стал функцией-членом?
Возьмите свой код и мой. Делайте в своём по одному изменению, которые присутствуют в моём и проверяйте работу. Так найдёте то, что вас интересует.
1
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
01.10.2013, 18:15  [ТС] #12
alsav22, приступаю
0
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.10.2013, 19:39 #13
То, что в вашем коде было оператором умножения, становится оператором *=, и записывается так :
C++
1
2
3
4
5
Matrix operator*= (Matrix& obj1, Matrix& obj2)
{
       obj1 = obj1 * obj2;
       return obj1;
}
То, что было оператором *=, становится оператором умножения. И всё начинает работать правильно.
1
Ryabchik
18 / 18 / 1
Регистрация: 09.01.2013
Сообщений: 163
01.10.2013, 21:14  [ТС] #14
alsav22, уже понял, спасибо большое.

Появилась другая проблема - при считывании не квадратных матриц - 0xC0000005: Нарушение прав доступа при чтении "0xccccccc0".
0
alsav22
01.10.2013, 21:23     Ошибка при работе с объектами
  #15

Не по теме:

Цитата Сообщение от Ryabchik Посмотреть сообщение
спасибо большое.
Цитата Сообщение от Ryabchik Посмотреть сообщение
Появилась другая проблема
Л/с получили?

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.10.2013, 21:23
Привет! Вот еще темы с ответами:

Ошибка при работе с очередью - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; struct link{ int data; link* next; };

ошибка при работе со стуктурами - C++
Возникает проблема при передаче структурных переменных в ф-цию Например: void showdatabase(struct Company *a,int i) { cin&gt;&gt;a.salary; ...

Ошибка при работе с файлом - C++
Пытался разобраться с записью и чтением из файла, посмотрел с десяток тем здесь, но столкнулся со странной (для меня) ошибкой. Вот,...

Ошибка при работе с массивом - C++
Добрый вечер всем. Пишу простую программу мат операций с массивами. И вот выдает такое окно с ошибкой. Помогите пожалуйста я не понимаю...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.10.2013, 21:23
Ответ Создать тему
Опции темы

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