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

delete внутри класса для самого класса - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Убрать нули после запятой http://www.cyberforum.ru/cpp-beginners/thread828681.html
Ребят помоги убрать ноли после запятой. Если введу 0,3000000000000000000000000000000000000000 то он пишет что больше 16 символов, а нужно чтобы отбросил нули и принял 0,3. Вот код: #include...
C++ нужна рекомендация по программе Помогите пожалуйста создать блок-схему к программе просто нужно перевести какое то число в двоичную систему программа уже готова #include "stdafx.h" #include<iostream> #include<string.h> ... http://www.cyberforum.ru/cpp-beginners/thread828677.html
C++ Выбор подходящего способа хранения\обработки данных
Здравствуйте! Передо мной встала задача выбора структуры данных, позволяющего хранить сортированные данные (в идеале позволяющая хранить пару ключ - значение) и и иметь возможность их добавления и...
C++ переделать из с++ в си
// Условие: Написать 3 функ-ии: // 1-ая: получает размерность массива, создает динамический массив и возвращает указатель на начало созданного массива. // 2-ая: получает адрес массива и его...
C++ лексический анализ дубль 2 http://www.cyberforum.ru/cpp-beginners/thread828654.html
у меня собственно говоря опять проблема. Лексический разбор многочлена. Только на этот раз я пошел другим путем. Вот что получилось. (код ниже). Вроде бы все работает, но если написать извращенный...
C++ Не могу создать шаблон Здорова господа! Снова пытаюсь написать шаблон и сново программа не компилируется #include <iostream> using std::cout; using std::endl; template<typename C> class String { class Cref; подробнее

Показать сообщение отдельно
awpe
2 / 2 / 0
Регистрация: 23.11.2011
Сообщений: 87

delete внутри класса для самого класса - C++

05.04.2013, 06:45. Просмотров 1004. Ответов 24
Метки (Все метки)

Доброго времени суток, пишу программу для работы с матрицами. По условию дали лишь несколько библиотек, ни векторов ни cstdio. Для динамического выделения памяти только new и delete. Итак что есть: класс CMatrix, основной элемент - это массив рядов матрицы, каждый ряд представлен классом CRow, который представляет собой массив double.

CRow:

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
class CRow {
public:
    CRow() {
        RowSize = 0;
    };
    CRow(int Cols) {
        RowElements = new double [Cols];
        for (int i = 0; i < Cols; i++) {
            RowElements[i] = 0.0;
        }
        RowSize = Cols;
    };
    CRow & operator=(const CRow & Old) {
        if (this == &Old) {
            return *this;
        }
        RowSize = Old.RowSize;
        RowElements = new double[Old.RowSize];
        for (int i = 0; i < Old.RowSize; i++) {
            RowElements[i] = Old.RowElements[i];
        }
        return *this;
    };
    ~CRow() {
        delete [] RowElements;
    };
    double & operator[](const int & ColNumber)const {
        return RowElements[ColNumber];
    };
    friend std::ostream & operator<<(std::ostream& os, const CRow& Row) {
        os << Row.RowElements[0];
        for (int i = 1; i < Row.RowSize; i++) {
            os << ", " << Row.RowElements[i];
        }
        return os;
    };
    friend class CMatrix;
protected:
    double * RowElements;
    int RowSize;
};
CMatrix:

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
class CMatrix {
public:
 
    CMatrix(int RCount, int ColsCount) {
        Rows = new CRow*[RCount];
        for (int i = 0; i < RCount; i++) {
            Rows[i] = new CRow(ColsCount);
        }
        RowsCount = RCount;
        ColumnsCount = ColsCount;
    };
 
    CMatrix(const CMatrix & Old) : RowsCount(Old.RowsCount), ColumnsCount(Old.ColumnsCount) {
        Rows = new CRow*[Old.RowsCount];
        for (int i = 0; i < RowsCount; i++) {
            Rows[i] = new CRow;
            *Rows[i] = *Old.Rows[i];
        }
    };
 
    ~CMatrix() {
        for (int i = 0; i < RowsCount; i++) {
            delete Rows[i];
        }
        delete [] Rows;
    };
 
    friend std::ostream & operator<<(std::ostream& os, const CMatrix& CM) {
        for (int i = 0; i < CM.RowsCount - 1; i++) {
            os << "{" << *CM.Rows[i] << " }," << std::endl;
        }
        os << "{" << *CM.Rows[CM.RowsCount - 1] << "}" << std::endl;
        return os;
    };
    CRow & operator[](const int & RowNumber)const {
        return *Rows[RowNumber];
    };
    friend class CRow;
 
    friend std::istream & operator>>(std::istream& is, CMatrix& CM) {
//здесь читается поток is потом надо этот поток отправить в матрицу, алгорит такой - читается поток на предмет 
//нормального формата, заодно выясняется сколько там рядов и столбцов
// потом создается временная матрица типа CMatrix, вызывается конструктор которму указывается сколько будет рядов 
//и столбцов
//потом абсолютно тем же алгоритмом что и в первом пункте (после is.seekg(0, is.beg); ) делается проход по is с записью 
//значений в матрицу.
// вот объясните мне неразумному - если нет реаалок то это единственый способ? Все что я могу еще придумать с new 
// это при нахождении элемента который выходит за границы размерности текущей матрицы-объекта, создавать 
//временный объект туду все сливать потом старый удалять и копировать туда указатель на новый... Мне кажется это 
//глупость, поэтому я сначала записываю все значения во временную матрицу а потом уже удаляю старую и приписываю 
//указатель. НО! валгринд потом находит один не освобожденный блок...
};
 
protected:
    CRow ** Rows;
    enum States {
        State_StartMatrix,
        State_StartLine,
        State_EndLine,
        State_EndMatrix,
        State_GotNumber,
        State_NextNumber,
        State_Error
    };
    int RowsCount;
    int ColumnsCount;
};
Вся программа как есть:
Кликните здесь для просмотра всего текста
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#ifndef __PROGTEST__
#include <iostream>
#include <sstream>
#include <iomanip>
#endif /* __PROGTEST__ */
 
class CRow {
public:
 
    CRow() {
        RowSize = 0;
    };
 
    CRow(int Cols) {
        RowElements = new double [Cols];
        for (int i = 0; i < Cols; i++) {
            RowElements[i] = 0.0;
        }
        RowSize = Cols;
    };
 
    CRow & operator=(const CRow & Old) {
        if (this == &Old) {
            return *this;
        }
        RowSize = Old.RowSize;
        RowElements = new double[Old.RowSize];
        for (int i = 0; i < Old.RowSize; i++) {
            RowElements[i] = Old.RowElements[i];
        }
        //std::cout << "padla" << std::endl;
        return *this;
    };
 
    ~CRow() {
        //std::cout << "padla" << std::endl;
        delete [] RowElements;
    };
 
 
    double & operator[](const int & ColNumber)const {
        return RowElements[ColNumber];
    };
 
    friend std::ostream & operator<<(std::ostream& os, const CRow& Row) {
        os << Row.RowElements[0];
        for (int i = 1; i < Row.RowSize; i++) {
            os << ", " << Row.RowElements[i];
        }
        return os;
    };
    friend class CMatrix;
protected:
    double * RowElements;
    int RowSize;
};
 
class CMatrix {
public:
 
    CMatrix(int RCount, int ColsCount) {
        Rows = new CRow*[RCount];
        for (int i = 0; i < RCount; i++) {
            Rows[i] = new CRow(ColsCount);
        }
        RowsCount = RCount;
        ColumnsCount = ColsCount;
    };
 
    CMatrix(const CMatrix & Old) : RowsCount(Old.RowsCount), ColumnsCount(Old.ColumnsCount) {
        Rows = new CRow*[Old.RowsCount];
        for (int i = 0; i < RowsCount; i++) {
            Rows[i] = new CRow;
            *Rows[i] = *Old.Rows[i];
        }
    };
 
    ~CMatrix() {
        for (int i = 0; i < RowsCount; i++) {
            delete Rows[i];
        }
        delete [] Rows;
    };
 
    friend std::ostream & operator<<(std::ostream& os, const CMatrix& CM) {
        for (int i = 0; i < CM.RowsCount - 1; i++) {
            os << "{" << *CM.Rows[i] << " }," << std::endl;
        }
        os << "{" << *CM.Rows[CM.RowsCount - 1] << "}" << std::endl;
        return os;
    };
    CRow & operator[](const int & RowNumber)const {
        return *Rows[RowNumber];
    };
    friend class CRow;
 
    friend std::istream & operator>>(std::istream& is, CMatrix& CM) {
        int RowSize = 0;
        int LinesCount = 0;
        int ColsTmp = 0;
        double d;
        char c;
        bool WhileBool = true;
        States state = State_StartMatrix;
        while (WhileBool) {
            switch (state) {
                case State_StartMatrix:
                    is >> std::skipws >> c;
                    if (c == '{') {
                        state = State_StartLine;
                    } else {
                        state = State_Error;
                    }
                    break;
                case State_StartLine:
                    is >> std::skipws >> c;
                    if (c == '{') {
                        state = State_NextNumber;
                    } else {
                        state = State_Error;
                    }
                    break;
                case State_NextNumber:
                    is >> std::skipws >> d;
                    if (!is.fail()) {
                        //RowElements[LinesCount][ColsTmp] = d;
                        ColsTmp++;
                        //cout << "num: '" << d << "'" << endl;
                        state = State_GotNumber;
                    } else {
                        state = State_Error;
                    }
                    break;
                case State_GotNumber:
                    is >> std::skipws >> c;
                    if (c == ',') {
                        state = State_NextNumber;
                    } else if (c == '}') {
                        state = State_EndLine;
 
                    } else {
                        state = State_Error;
                    }
                    break;
                case State_EndLine:
                    LinesCount++;
                    if (LinesCount > 1) {
                        if (RowSize != ColsTmp) {
                            state = State_Error;
                            break;
                        }
                    }
                    if (LinesCount == 1) {
                        RowSize = ColsTmp;
                    }
                    ColsTmp = 0;
                    is >> std::skipws >> c;
                    if (c == ',') {
                        state = State_StartLine;
                    } else if (c == '}') {
                        state = State_EndMatrix;
                    } else {
                        state = State_Error;
                    }
                    break;
                case State_EndMatrix:
                    WhileBool = false;
                    break;
                case State_Error:
                    is.setstate(std::ios::failbit);
                    WhileBool = false;
                    break;
            }
        }
 
        if (!is.fail()) {
 
 
            //            for (int i = 0; i < LinesCount; i++) {
            //                for (int j = 0; j < RowSize - 1; j++) {
            //                    std::cout << "" << RowElements[i][j] << ",";
            //                }
            //                std::cout << "" << RowElements[i][RowSize - 1] << "";
            //                std::cout << std::endl;
            //            }
            //            std::cout << "Rows:\t" << LinesCount << std::endl;
            //            std::cout << "Cols:\t" << RowSize << std::endl;
 
 
            CMatrix *tmpMatrix = new CMatrix(LinesCount, RowSize);
            is.seekg(0, is.beg);
            LinesCount = 0;
            RowSize = 0;
            ColsTmp = 0;
 
 
            bool WhileBool = true;
            States state = State_StartMatrix;
            while (WhileBool) {
                switch (state) {
                    case State_StartMatrix:
                        is >> std::skipws >> c;
                        if (c == '{') {
                            state = State_StartLine;
                        } else {
                            state = State_Error;
                        }
                        break;
                    case State_StartLine:
                        is >> std::skipws >> c;
                        if (c == '{') {
                            state = State_NextNumber;
                        } else {
                            state = State_Error;
                        }
                        break;
                    case State_NextNumber:
                        is >> std::skipws >> d;
                        if (!is.fail()) {
                            //RowElements[LinesCount][ColsTmp] = d;
                            tmpMatrix->Rows[LinesCount]->operator [](ColsTmp) = d;
                            ColsTmp++;
                            //cout << "num: '" << d << "'" << endl;
                            state = State_GotNumber;
                        } else {
                            state = State_Error;
                        }
                        break;
                    case State_GotNumber:
                        is >> std::skipws >> c;
                        if (c == ',') {
                            state = State_NextNumber;
                        } else if (c == '}') {
                            state = State_EndLine;
                        } else {
                            state = State_Error;
                        }
                        break;
                    case State_EndLine:
                        LinesCount++;
                        if (LinesCount > 1) {
                            if (RowSize != ColsTmp) {
                                state = State_Error;
                                break;
                            }
                        }
                        if (LinesCount == 1) {
                            RowSize = ColsTmp;
                        }
                        ColsTmp = 0;
                        is >> std::skipws >> c;
                        if (c == ',') {
                            state = State_StartLine;
                        } else if (c == '}') {
                            state = State_EndMatrix;
                        } else {
                            state = State_Error;
                        }
                        break;
                    case State_EndMatrix:
                        WhileBool = false;
                        break;
                    case State_Error:
                        is.setstate(std::ios::failbit);
                        WhileBool = false;
                        break;
                }
            }
 
 
 
            for (int i = 0; i < CM.RowsCount; i++) {
                delete CM.Rows[i];
            }
            delete [] CM.Rows;
 
            
            CM = *tmpMatrix;
 
            return is;
        }
        return is;
    };
 
 
 
protected:
    CRow ** Rows;
 
    enum States {
        State_StartMatrix,
        State_StartLine,
        State_EndLine,
        State_EndMatrix,
        State_GotNumber,
        State_NextNumber,
        State_Error
    };
    int RowsCount;
    int ColumnsCount;
};
 
int main(int argc, char** argv) {
    std::istringstream is;
    std::ostringstream os;
 
 
    CMatrix a(2, 3);
    a[0][0] = 1;
    a[0][1] = 2;
    a[0][2] = 3;
    a[1][0] = 4;
    a[1][1] = 5;
    a[1][2] = 6;
    const CMatrix b = a;
    std::cout << b[1][2] << std::endl;
 
    CMatrix d(1, 1);
    d[0][0] = -1;
 
    std::cout << d;
 
 
 
 
    is . clear();
    is . str("{ { 1.1782, 2, 3, 4 }, { 4, 3, 2, 1 } } ");
 
 
    is >> a;
 
 
    return 0;
}


Внутри оператора >> класса CMatrix я втсавил комментарии и вопрос.

В общем моя проблема в том что я привык в malloc/realloc когда учил си, для динамического распределения памяти, каждый раз создавать временный объект чтобы скопировать туда то что есть и потом приравнивать указатели и удлалять старый... Вероятно я просто не умею готовить new/delete расскажите/научите что я делаю не так, где можно было бы решить проще? кстати из за отсутствия realloc в программе приходится в операторе >> два раза один и тот же кусок кода использовать, так как на ходу увеличивать размер не получится. Два класса нужны, чтобы перегрузить оператор [][];

И еще раз нет ни векторов ни стрингов - ничего кроме указынных под спойлером библиотек.

Добавлено через 2 минуты
P.S. Если вы студент FIT, большая просьба не копипастить, все равно потом я докажу что это мой код, но время потеряют все...

Добавлено через 7 минут
Валгринд показывает утечку здесь:
C++
1
CMatrix *tmpMatrix = new CMatrix(LinesCount, RowSize);
что странно, ведь я делаю вот так:
C++
1
2
3
4
            for (int i = 0; i < CM.RowsCount; i++) {
                delete CM.Rows[i];
            }
            delete [] CM.Rows;
что очищает все динамические структуры в текущей матрице, потом вот так:
C++
1
CM = *tmpMatrix;
т.е. имели ссылку на CM типа CMatrix, данный вызов, как я понимаю вызывает конструктор для CMatrix, создается мелкая копия (т.е. только указатели присваиваются) и вуаля - в CM теперь объект tmpMatrix, где тут утечка?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru