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

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

23.10.2018, 17:37. Показов 3991. Ответов 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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
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
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 1
24.10.2018, 17:41
Цитата Сообщение от marakesh Посмотреть сообщение
Нас учил так делать семинарист.
Что-то я сомневаюсь что он именно так учил делал.
Ну, либо шарлатан какой-то попался.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
24.10.2018, 17:47
Цитата Сообщение от marakesh Посмотреть сообщение
Эта программа может обойтись без деструкторов?
Да, для объектов созданных на стеке он вызовется автоматически как только выдете за пределы видимости.
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
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
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,218
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
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
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
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru