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

Ошибка при вызове деструктора (при вызове delete в деструкторе)

23.10.2018, 17:37. Показов 3867. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не могу найти ошибку, при вызове деструктора от класса, который был создан при помощи конструктора с параметром const String &, возникает ошибка - не работает delete[]. Остальные деструкторы для других классов работают нормально.

Код:
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
#include <iostream>
 
using namespace std;
 
//------------------------------------------//
 
int strLen(char *str)
{
    int i = 0;
    for (; str[i] != 0; i++);
    return i;
}
 
void strCopy(char *to_str, char *from_str)
{
    int l = strLen(to_str);
    for (int i = 0; i < l; i++)
    {
        to_str[i] = from_str[i];
    }
    to_str[l] = '\0';
}
 
//------------------------------------------//
 
class String
{
private:
    char *data;
    int length;
public:
    String();
    String(char *);
    String(const String &);
    ~String();
    String& operator=(const String &);
    String& operator+=(const String &);
    friend String operator+(const String &, const String &);
    void getDataStr()
    {
        cout << data << endl;
    }
};
 
//------------------------------------------//
 
String::String()
{
    data = new char[1];
    data[0] = '\0';
    length = 1;
}
 
String::String(char *str)
{
    data = new char[strLen(str) + 1];
    strCopy(data, str);
    length = strLen(data);
}
 
String::String(const String &orig)
{
    data = new char[strLen(orig.data)];
    strCopy(data, orig.data);
    length = strLen(data);
}
 
String::~String()
{
    delete[] this->data;
    length = 0;
}
 
String& String::operator=(const String &orig)
{
    delete[] this->data;
    this->data = new char[strLen(orig.data) + 1];
    strCopy(this->data, orig.data);
    length = strLen(this->data);
    return *this;
}
 
String& String::operator+=(const String &orig)
{
    int size = strLen(this->data) + strLen(orig.data);
    char* tmp = new char[size + 1];
    int l = strLen(this->data);
    for (int i = 0; i < l; i++)
    {
        tmp[i] = this->data[i];
    }
    for (int j = 0, k = l; k < size; j++, k++)
    {
        tmp[k] = orig.data[j];
    }
    tmp[size] = '\0';
    delete[] this->data;
    this->data = tmp;
    length = strLen(this->data);
    return *this;
}
 
String operator+(const String &a, const String &b)
{
    int size = strLen(a.data) + strLen(b.data);
    char *tmp = new char[size + 1];
    for (int i = 0; i < a.length; i++)
    {
        tmp[i] = a.data[i];
    }
    for (int j = 0, k = a.length; k < size; j++, k++)
    {
        tmp[k] = b.data[j];
    }
    tmp[size] = '\0';
    return tmp;
}
 
//------------------------------------------//
 
int main()
{
    setlocale(LC_ALL, "rus");
    char* b = new char[10];
    for (int i = 0; i < 9; i++)
    {
        cin >> b[i];
    }
    b[9] = '\0';
    char* c = new char[10];
    for (int i = 0; i < 9; i++)
    {
        cin >> c[i];
    }
    c[9] = '\0';
    String q(c);
    String A;
    String B(b);
    String C(q);
 
    cout << endl << "/--------0---------/" << endl << endl;
 
    B.getDataStr();
    C.getDataStr();
 
    cout << endl << "/--------1---------/" << endl << endl;
 
    A = B;
    A.getDataStr();
 
    cout << endl << "/--------2---------/" << endl << endl;
 
    A = B + C;
    A.getDataStr();
 
    cout << endl << "/--------3---------/" << endl << endl;
 
    B += C;
    B.getDataStr();
 
    q.~String();
    A.~String();
    B.~String();
    C.~String();
 
    system("pause");
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.10.2018, 17:37
Ответы с готовыми решениями:

При вызове деструктора в строке delete[] data выбрасывается исключение
вот как раз вопрос по этой теме. программа отрабатывает все команды и в конце при вызове деструктора в строке delete data выбрасывает...

Ошибка при вызове деструктора
Здравствуйте, помогите разобраться с проблемой, она довольно распространенная и на форуме куча сообщений про это но в моей программе я...

Ошибка при вызове деструктора
Всем привет ! Есть класс class building { private: string *location_street; unsigned int *number_of_building; public...

22
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.10.2018, 00:56
Цитата Сообщение от marakesh Посмотреть сообщение
C++
1
2
3
4
    q.~String();
    A.~String();
    B.~String();
    C.~String();
Кто это вас так делать научил? Это неверно для автоматических объектов, уберите.
0
0 / 0 / 0
Регистрация: 23.10.2018
Сообщений: 3
24.10.2018, 17:05  [ТС]
Нас учил так делать семинарист. Эта программа может обойтись без деструкторов?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
24.10.2018, 17:20
Цитата Сообщение от marakesh Посмотреть сообщение
Эта программа может обойтись без деструкторов?
вообще нет, в вашем случае вероятно да..
Цитата Сообщение от marakesh Посмотреть сообщение
strLen(orig.data) + 1
у вас же есть поле length
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
24.10.2018, 17:41
Цитата Сообщение от marakesh Посмотреть сообщение
Нас учил так делать семинарист.
Что-то я сомневаюсь что он именно так учил делал.
Ну, либо шарлатан какой-то попался.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
24.10.2018, 17:47
Цитата Сообщение от marakesh Посмотреть сообщение
Эта программа может обойтись без деструкторов?
Да, для объектов созданных на стеке он вызовется автоматически как только выдете за пределы видимости.
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.10.2018, 18:10
Цитата Сообщение от marakesh Посмотреть сообщение
Эта программа может обойтись без деструкторов?
Деструкторы вызываются автоматически для автоматических объектов. Они поэтому и называются - автоматические.
Сами деструкторы нужны, конечно же. Но вот вызывать их явно вы не должны, о чем я вам выше и сказал.

Добавлено через 2 минуты
Собственно ошибка в том, что компилятор все равно будет генерировать код автоматического вызова деструктора для ваших объектов. Не смотря на ваш явный вызов. Отсюда получаем ошибку двойного освобождения памяти, которая у вас проявилась вот так
Цитата Сообщение от marakesh Посмотреть сообщение
ошибка - не работает delete[]
Добавлено через 1 минуту
Цитата Сообщение от marakesh Посмотреть сообщение
Нас учил так делать семинарист
Если он вас именно так учил, то с прискорбием можно заключить, что язык C++ он не знает.
С прискорбием для вас, конечно же. Вам же у него и дальше учиться, я так понимаю.
2
44 / 20 / 14
Регистрация: 23.10.2018
Сообщений: 103
24.10.2018, 18:21
Цитата Сообщение от aLarman Посмотреть сообщение
Да, для объектов созданных на стеке он вызовется автоматически как только выдете за пределы видимости.
можно использовать, например, std::unique_ptr
1
0 / 0 / 0
Регистрация: 23.10.2018
Сообщений: 3
24.10.2018, 21:33  [ТС]
Всем большое спасибо!
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12922 / 6789 / 1818
Регистрация: 18.10.2014
Сообщений: 17,176
24.10.2018, 21:41
Цитата Сообщение от marakesh Посмотреть сообщение
C++
1
2
3
4
5
6
String::String()
{
  data = new char[1];
  data[0] = '\0';
  length = 1;
}
В дополнение к уже сказанному: почему здесь length вдруг получает значение 1?

Это, в частности, приведет в неправильной работе всех методов, которые используют значение length из сконструированного по умолчанию объекта.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
24.10.2018, 21:47
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void strCopy(char *to_str, char *from_str)
{
    int l = strLen(to_str);//Зачем Вы определяете длину строки, которую нужно заменить?
    for (int i = 0; i < l; i++)//так скопируются только столько символов, сколько было в строке назначения
    {
        to_str[i] = from_str[i];//а если в строке-источнике не хватит символов, то беда
    }
    to_str[l] = '\0';//Этот ноль там уже есть, Вы же переписали символы до l
}
 
//при таком подходе, строчки
    data = new char[strLen(str) + 1];//вообще неверны, т.к.
    strCopy(data, str);//data смотрит на неинициализированную память, в которой strCopy будет искать нолик
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
25.10.2018, 12:59
Цитата Сообщение от sty4ent Посмотреть сообщение
можно использовать, например, std::unique_ptr
Его нужно использовать если выделяете и создаете объект в куче, а не на стеке. И тогда его использование облегчит жизнь - на нужно будет вызывать удаление по указателю объекта самостоятельно(т.к у объекта unique_ptr так же будет автоматически вызван деструктор после выхода из зоны видимости, т.к этот объект на стеке.). И это скорее совет "нужно использовать", что в конечном итоге вовсе и не обязательно )

Добавлено через 2 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
C++
1
to_str[l] = '\0';//Этот ноль там уже есть, Вы же переписали символы до l
Кажется Вы заблуждаетесь(или ткните меня носом), strLen вернет длину не включая символа "конец строки"

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Деструкторы вызываются автоматически для автоматических объектов. Они поэтому и называются - автоматические.
в Плюсах есть автоматические объекты O_o ? не видел ничего подобного в стандарте

0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
25.10.2018, 13:01
aLarman,
C++
1
2
3
char str[] = { 'a', 'b', 'c', '\0' };
strLen(str) // вернет 3
std::cout << str[3]; // что получаем?)
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
25.10.2018, 13:04
Цитата Сообщение от aLarman Посмотреть сообщение
в Плюсах есть автоматические объекты ? не видел ничего подобного в стандарте
Начинается...
http://eel.is/c++draft/basic.stc#auto
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
25.10.2018, 13:07

Не по теме:

Что то не понимаю сути вопроса, как это что то доказывает или опровергает?
Вы цикл обойдите с конкретными цифрами и увидите в чем дело



Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Это конечно прекрасно, но там нет и слова про "автоматические объекты", есть только про "автоматическая длительность хранения " (уж простите не могу точный перевод предоставить)

0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
25.10.2018, 13:10
Цитата Сообщение от aLarman Посмотреть сообщение
Это конечно прекрасно, но там нет и слова про "автоматические объекты"
Автоматические объекты = объекты с automatic storage duration.
Точно так же как статические объекты = объекты со static storage duration.

Т.е. когда говорят статические объекты - вас это не смущает, а с автоматическими вдруг накладка вышла?
Или у вас просто норма выработки по буквоедству на сегодня не выполнена?
Тогда спешу вас расстроить: я в этой теме не давал формальных определений, чтобы к ним можно было так придираться.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
25.10.2018, 13:12

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
C++
1
to_str[l] = '\0';//Этот ноль там уже есть, Вы же переписали символы до l
Цитата Сообщение от aLarman Посмотреть сообщение
Кажется Вы заблуждаетесь(или ткните меня носом), strLen вернет длину не включая символа "конец строки"
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
std::cout << str[3]; // что получаем?)
Так и быть уточню, НЕ включая l переписаны символы



Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Т.е. когда говорят статические объекты - вас это не смущает, а с автоматическими вдруг накладка вышла?
Или у вас просто норма выработки по буквоедству на сегодня не выполнена?
Тогда спешу вас расстроить: я в этой теме не давал формальных определений, чтобы к ним можно было так придираться.
Так не спорю, товарищ, а кто то запомнит это и будет утверждать что есть именно "автоматически объекты"
Нормы не выполняю, природное занудство, пардоньте :)

0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
25.10.2018, 13:13
Цитата Сообщение от aLarman Посмотреть сообщение
Так не спорю, товарищ, а кто то запомнит это и будет утверждать что есть именно "автоматически объекты"
И он будет прав. Вы ерундой занимаетесь.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
25.10.2018, 13:35
aLarman,
Цитата Сообщение от Croessmah Посмотреть сообщение
C++
1
to_str[l] = '\0';//Этот ноль там уже есть, Вы же переписали символы до l
Цитата Сообщение от aLarman Посмотреть сообщение
Кажется Вы заблуждаетесь(или ткните меня носом), strLen вернет длину не включая символа "конец строки"
Вернет без, но именно в той строке(вернее после выхода из цикла) на позиции l в массиве to_str действительно уже будет записан '\0'. Зачем еще раз его туда писать?)

Добавлено через 13 минут
C++
1
2
3
4
5
6
7
8
9
10
11
void strCopy(char *to_str, char *from_str)
{
    // на вход на же приходит строка вида { 'a', 'b', 'c', '\0' }
    // с терминирующим нулем, ну т.е. не она сама, а только 
    // указатель на первый эл. ато еще и тут придирку найдут :)
    // но сути не меняет, в памяти она такая будет
 
    int l = strLen(to_str); // получаем длину == 3
    for (int i = 0; i < l; ++i) // в цикле переписали все до '\0' он остался 
    to_str[l] = '\0'; // итого не имеет смысла
}
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
25.10.2018, 13:36
Цитата Сообщение от aLarman Посмотреть сообщение
Так не спорю, товарищ, а кто то запомнит это и будет утверждать что есть именно "автоматически объекты"
Нормы не выполняю, природное занудство, пардоньте
А я вот свою не выполнил, так что вот вам аргументы:

В стандарте их тоже так называют периодически.

The destructor is invoked for each automatic object of class type constructed, but not yet destroyed, since the try block was entered.
http://eel.is/c++draft/except.ctor#2

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X's direct non-variant non-static data members, the destructors for X's non-virtual direct base classes and, if X is the most derived class ([class.base.init]), its destructor calls the destructors for X's virtual base classes.
http://eel.is/c++draft/class.dtor#9

Потому что эти фразы синонимичны по принципу, указанному выше:
Цитата Сообщение от DrOffset Посмотреть сообщение
Автоматические объекты = объекты с automatic storage duration.
Статические объекты = объекты со static storage duration.
Локальные к потоку объекты = объекты с thread local storage duration.
Динамические объекты = объекты с dynamic storage duration.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.10.2018, 13:36
Помогаю со студенческими работами здесь

Ошибка при вызове деструктора
Не могу дописать лабу... Надо создать 4 класса, описать поля и методы. Выкладываю исходники: Самый главный класс - Order. Выбивает ошибку в...

Ошибка при вызове деструктора
Программа компилиться нормально,но после выполнения system(&quot;pause&quot;); выползает непонятное окно,и указывает на ошибку в деструкторе.В чем...

Ошибка при вызове деструктора
Добрый вечер! Почему при вызове деструктора вылетает ошибка после компиляции кода? #include &lt;conio.h&gt; #include &lt;iostream&gt; ...

Ошибка при вызове деструктора
Подскажите, что не так с этим деструктором? Просто выдает ошибку. Если его убираю то все идет норм. Если же оставляю, то куча всяких...

Ошибка при вызове деструктора
По окончании программы выдает ошибку #include &lt;string.h&gt; #include &lt;iostream&gt; using namespace std; class nik //объявление...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru