Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
46 / 46 / 18
Регистрация: 25.10.2011
Сообщений: 183

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

24.03.2013, 16:46. Показов 1195. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.03.2013, 16:46
Ответы с готовыми решениями:

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

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

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

12
...
 Аватар для anmartex
1910 / 1329 / 966
Регистрация: 12.02.2013
Сообщений: 2,172
24.03.2013, 19:21
Hunter13ua, код в принципе верен (правда можно было бы и 1-ой вспомогательной переменной воспользоваться, но это мелочи). Покажите весь класс.
0
46 / 46 / 18
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 19:29  [ТС]
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
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
24.03.2013, 19:37
Цитата Сообщение от Hunter13ua Посмотреть сообщение
#include "LongNumbers.cpp"
убери это и больше никогда не инклюдь срр файлы
0
46 / 46 / 18
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 19:46  [ТС]
Kuzia domovenok, а объяснить почему можно? Я же не в курсе дела
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
24.03.2013, 19:51
потому что в языке С++ раздельная компиляция. СРР Файлы не должны практически ничего знать друг о друге.
0
46 / 46 / 18
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 19:55  [ТС]
Kuzia domovenok, понял. А если вбить весь код из LongNumbers.cpp ниже в заголовочный файл - будет существенная разница ?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
24.03.2013, 19:55
Цитата Сообщение от Hunter13ua Посмотреть сообщение
C++
1
2
3
LongNum A; LongNum B;
A.Readln(); B.Readln();
A=B;
A и B ссылаются на одну и туже память, и на момент вызова деструктора А, объект В уже освободит память, а деструктор А освободит повторно - что и приводит к ошибке
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
24.03.2013, 19:59
Говоря простым языком,
#include команда препроцессора, которая говорит, что перед компиляцией срр файла в это место будет скопипащен текст из другого файла. Обычно это требуется для добавления заголовочных (.h) файлов в программу. Но это не значит, что всю программу следует инклюдить в один файл, а затем компилировать.

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

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

Добавлено через 3 минуты
Kuzia domovenok, понял, благодарю за разъяснение
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
24.03.2013, 20:29
Цитата Сообщение от Hunter13ua Посмотреть сообщение
так я ведь переопределил оператор присваивания. Он удаляет старую память, создаёт новую и туда уже копирует значения из второго объекта. Разве ошибся ?
вы определили свой оператор равно.
для переопределения параметр должен передаваться: по значению, по ссылке, по ссылке на константу(+ volatile опционально к последним двум вариантам)
0
46 / 46 / 18
Регистрация: 25.10.2011
Сообщений: 183
24.03.2013, 23:27  [ТС]
Окей, тогда будьте добры, помогите с операцией присваивания
Классы только начал изучать, соответственно и операции.
Попытался переписать нечто:
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
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
25.03.2013, 00:00
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.03.2013, 00:00
Помогаю со студенческими работами здесь

Ошибка при работе delete в деструкторе
enum place { first = 1, second }; class Passanger { public: Passanger(); void Call(); void PushButton(); int...

Ошибка в деструкторе или перегрузке оператора C++ ООП
#include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; #include &lt;windows.h&gt; using namespace std; ...

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

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

Ошибка в деструкторе
Всем привет. Пытаюсь написать что-то типа динамического массива строк, и все шло довольно хорошо пока не начал писать деструктор. ...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru