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

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

Войти
Регистрация
Восстановить пароль
 
Hunter13ua
46 / 46 / 5
Регистрация: 25.10.2011
Сообщений: 183
#1

Классы - ошибка в деструкторе - C++

24.03.2013, 16:46. Просмотров 496. Ответов 12
Метки нет (Все метки)

У меня сейчас такое "задание": опередить класс длинного целого числа (длинная арифметика), для сохранения которого необходимо использовать однонаправленный связной список. Конструктор создаёт всего-лишь первый элемент списка "Head" со значениями data = NULL, next = NULL. При чтении числа значения заносятся в конец списка.
В итоге данный деструктор выдаёт ошибку при удалении двух чисел в конце работы программы:
C++
1
2
3
4
5
6
7
8
9
10
11
LongNum::~LongNum()
{
        LongNum *temp1 = this->Head;
        LongNum *temp2;
        while ( temp1 != NULL )
        {
                temp2 = temp1;
                temp1 = temp1->next;
                free(temp2);
        }
}
Для выделении памяти использую malloc.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.03.2013, 16:46
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Классы - ошибка в деструкторе (C++):

Ошибка в деструкторе - C++
Программа работает без ошибок и полный её код не выкладываю. Но при выходе из программы получаю вот такую ошибку: В программе я...

Ошибка в деструкторе - C++
есть базовый абстрактный класс и есть производный от него: #ifndef EMPLOY_H #define EMPLOY_H class Employee { public: ...

Ошибка в деструкторе - C++
Когда удаляю объект класса hotel, в деструкторе вызывается delete для поля этого объекта - динамически созданного связного списка. И...

Возникает ошибка при удалении динамического массива символов в деструкторе класса - C++
Всем привет. Есть приватная переменная, указатель на строку wchar_t *pUAgent; В конструкторе я ее инициализирую: pUAgent =...

При работе с free в деструкторе ошибка "Invalid address specified to RtlValidateHeap" - C++
Доброго времени суток, господа эксперты и дамы эксперты. Объясните пожалуйста почему программа вылетает с ошибкой "program.exe has...

Повисание в деструкторе - C++
Есть такой код: //staff.h class staff abstract { protected: int salary; char* name; char* id; static staff* start;

12
anmartex
...
1708 / 1201 / 496
Регистрация: 12.02.2013
Сообщений: 1,978
24.03.2013, 19:21 #2
Hunter13ua, код в принципе верен (правда можно было бы и 1-ой вспомогательной переменной воспользоваться, но это мелочи). Покажите весь класс.
0
Hunter13ua
46 / 46 / 5
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 19:29  [ТС] #3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------------------------------------------------------
 
#pragma hdrstop
 
//---------------------------------------------------------------------------
 
#pragma argsused
#include <stdio.h>
#include <stdlib.h>
#include "LongNumbers.cpp"
int main(int argc, char* argv[])
{
        LongNum A; LongNum B;
        A.Readln(); B.Readln();
        A=B;
        A.Write(A.Head);
        printf("\n");
        system("pause");
        return 0;
}
//---------------------------------------------------------------------------
LongNumbers.cpp
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
//---------------------------------------------------------------------------
 
#pragma hdrstop
 
#include "LongNumbers.h"
#include <stdio.h>
#include <alloc.h>
#include <string.h>
 
#define max( a, b ) ( (a < b) ? a : b )
 
LongNum::LongNum()
{
        this->Head = (LongNum*) malloc(sizeof(LongNum));
        this->Head->data = NULL;
        this->Head->next = NULL;
}
 
LongNum::~LongNum()
{
        LongNum *temp1 = this->Head;
        LongNum *temp2;
        while ( temp1 != NULL )
        {
                temp2 = temp1;
                temp1 = temp1->next;
                free(temp2);
        }
}
 
void LongNum::add_list(char d)
{
        LongNum* temp1 = this->Head;
        LongNum* temp2 = (LongNum*) malloc(sizeof(LongNum));
        temp2->data = d;
        temp2->next = NULL;
        if ( this->Head == NULL )
                this->Head = temp2;
        else
        {
                while ( temp1->next != NULL)
                        temp1 = temp1->next;
                temp1->next = temp2;
        }
}
 
void LongNum::Readln()
{
        char * string = new char [255];
        gets(string);
        size_t len = strlen(string);
        for(int i=len-1; i>=0; i--)
        {
                this->add_list(string[i]);
        }
}
 
size_t LongNum::GetSize()
{
        size_t size = 0;
        LongNum *temp = this->Head;
        if ( temp != NULL )
                size++;
        while ( temp->next != NULL )
        {
                size++;
                temp = temp->next;
        }
        return size;
}
 
void LongNum::Write(LongNum *head)
{
        if ( head != NULL )
        {
                if ( head->next != NULL )
                        LongNum::Write(head->next);
                printf("%c",head->data);
        }
}
 
void LongNum::Normalize()
{
        LongNum *temp = this->Head;
        if ( this->Head != NULL )
                if ( (this->Head->next == NULL) && ( this->Head->data == '0' ) )
                {
                        this->~LongNum();
                        puts("Normalization completed. Number was empty. Deleted.");
                }
        LongNum *pos = NULL;
        while ( temp->next != NULL )
        {
                if ( (temp->next->data == '0') && (pos == NULL) )
                        pos = temp;
                if ( temp->next->data != '0' ) pos = NULL;
                temp = temp->next;
        }
        if ( pos != NULL )
        {
                temp = pos->next;
                pos->next = NULL;
                pos = temp;
        }
        while ( pos != NULL )
        {
                temp = pos;
                pos = pos->next;
                free(temp);
        }
        printf("Normalization done.\n");
}
 
bool LongNum::check()
{
        LongNum *temp = this->Head;
        bool flag = false;
        while (temp->next != NULL)
        {
                if (temp->data != '0') flag = true;
                temp = temp->next;
        }
        return flag;
}
 
void LongNum::operator=(LongNum *A)
{
        LongNum *temp1 = this->Head;
        LongNum *temp2;
        while ( temp1->next != NULL )
        {
                temp2 = temp1;
                temp1 = temp1->next;
                free(temp2);
        }
        if (temp1 != NULL)
                free(temp1);
        this->Head = NULL;
 
        temp1 = A->Head;
        while ( temp1 != NULL )
        {
                this->add_list(temp1->data);
        }
}
//---------------------------------------------------------------------------
#pragma package(smart_init)

LongNumbers.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//---------------------------------------------------------------------------
 
#ifndef LongNumbersH
#define LongNumbersH
#include <stddef.h>
class LongNum {
        private:
                char data;
                LongNum *next;
                void add_list(char d);
        public:
                LongNum *Head;
                LongNum();
                ~LongNum();
                void Readln();
                size_t GetSize();
                void Write(LongNum *head);
                void Normalize();
                bool check();
                void operator=(LongNum *A);
};
//---------------------------------------------------------------------------
#endif
0
Kuzia domovenok
1957 / 1810 / 142
Регистрация: 25.03.2012
Сообщений: 6,274
Записей в блоге: 1
24.03.2013, 19:37 #4
Цитата Сообщение от Hunter13ua Посмотреть сообщение
#include "LongNumbers.cpp"
убери это и больше никогда не инклюдь срр файлы
0
Hunter13ua
46 / 46 / 5
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 19:46  [ТС] #5
Kuzia domovenok, а объяснить почему можно? Я же не в курсе дела
0
Kuzia domovenok
1957 / 1810 / 142
Регистрация: 25.03.2012
Сообщений: 6,274
Записей в блоге: 1
24.03.2013, 19:51 #6
потому что в языке С++ раздельная компиляция. СРР Файлы не должны практически ничего знать друг о друге.
0
Hunter13ua
46 / 46 / 5
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 19:55  [ТС] #7
Kuzia domovenok, понял. А если вбить весь код из LongNumbers.cpp ниже в заголовочный файл - будет существенная разница ?
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
24.03.2013, 19:55 #8
Цитата Сообщение от Hunter13ua Посмотреть сообщение
C++
1
2
3
LongNum A; LongNum B;
A.Readln(); B.Readln();
A=B;
A и B ссылаются на одну и туже память, и на момент вызова деструктора А, объект В уже освободит память, а деструктор А освободит повторно - что и приводит к ошибке
0
Kuzia domovenok
1957 / 1810 / 142
Регистрация: 25.03.2012
Сообщений: 6,274
Записей в блоге: 1
24.03.2013, 19:59 #9
Говоря простым языком,
#include команда препроцессора, которая говорит, что перед компиляцией срр файла в это место будет скопипащен текст из другого файла. Обычно это требуется для добавления заголовочных (.h) файлов в программу. Но это не значит, что всю программу следует инклюдить в один файл, а затем компилировать.

Раздельная компиляция, как я её понимаю, это такая штука, что после того, как cpp файл прошёл препроцессор, он может компилироваться вне зависимости от наличия или отсутствия других срр файлов. Прочие срр могли скомпилироваться с ошибками или вообще их не хватает - не важно. компилятор обрабатывает срр файлы по-одному и строит из них куски кода.

Затем эти куски кода связываются linkerом. И только при этом процессе уже складываются в единый экзе файл. Поэтому не надо делать это раньше времени.
1
Hunter13ua
46 / 46 / 5
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 20:07  [ТС] #10
Jupiter, так я ведь переопределил оператор присваивания. Он удаляет старую память, создаёт новую и туда уже копирует значения из второго объекта. Разве ошибся ?

Добавлено через 3 минуты
Kuzia domovenok, понял, благодарю за разъяснение
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
24.03.2013, 20:29 #11
Цитата Сообщение от Hunter13ua Посмотреть сообщение
так я ведь переопределил оператор присваивания. Он удаляет старую память, создаёт новую и туда уже копирует значения из второго объекта. Разве ошибся ?
вы определили свой оператор равно.
для переопределения параметр должен передаваться: по значению, по ссылке, по ссылке на константу(+ volatile опционально к последним двум вариантам)
0
Hunter13ua
46 / 46 / 5
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 23:27  [ТС] #12
Окей, тогда будьте добры, помогите с операцией присваивания
Классы только начал изучать, соответственно и операции.
Попытался переписать нечто:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
LongNum & LongNum::operator=(LongNum *A)
{
        LongNum *temp1 = this->Head;
        LongNum *temp2;
        while ( temp1->next != NULL )
        {
                temp2 = temp1;
                temp1 = temp1->next;
                free(temp2);
        }
 
        this->Head = (LongNum*) malloc(sizeof(LongNum));
        this->Head->data = NULL;
        this->Head->next = NULL;
 
        temp2 = this->Head;
        temp1 = A->Head;
        while ( temp1 != NULL )
        {
                temp2->add_list(temp1->data);
                temp1 = temp1->next;
        }
}
Не работает(
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
25.03.2013, 00:00 #13
Цитата Сообщение от Hunter13ua Посмотреть сообщение
LongNum & LongNum::operator=(LongNum *A)
C++
1
2
3
4
5
6
7
8
9
LongNum& LongNum::operator = (const LongNum& A)
{
    if (this != &A)
    {
    //копируем
    }
    
    return *this;
}
0
25.03.2013, 00:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.03.2013, 00:00
Привет! Вот еще темы с ответами:

Зависание на деструкторе. - C++
Всем доброго времени суток! Проблема такая: есть класс cData в нём статический член staric int amount, при вызове конструктора...

Вылет программы на деструкторе - C++
Здравствуйте, подскажите пожалуйста что не так? Программа не корректно завершается #pragma once #pragma warning(disable:4996) ...

Оператор delete в деструкторе - C++
Здравствуйте, нужна помощь, есть класс и функция к которую передается этот класс: #include&lt;iostream&gt; using namespace std; class...

Освобождение памяти в деструкторе - C++
Здравствуйте у меня есть три класса: class Date { int iDay, iMonth, iYear; public: Date(); Date(Date&amp;); Date(int Day,...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

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