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

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

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

Author24 — интернет-сервис помощи студентам
Не могу найти ошибку, при вызове деструктора от класса, который был создан при помощи конструктора с параметром 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
19417 / 10034 / 2445
Регистрация: 30.01.2014
Сообщений: 17,697
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
18124 / 10708 / 2063
Регистрация: 27.09.2012
Сообщений: 26,996
Записей в блоге: 1
24.10.2018, 17:41
Цитата Сообщение от marakesh Посмотреть сообщение
Нас учил так делать семинарист.
Что-то я сомневаюсь что он именно так учил делал.
Ну, либо шарлатан какой-то попался.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
24.10.2018, 17:47
Цитата Сообщение от marakesh Посмотреть сообщение
Эта программа может обойтись без деструкторов?
Да, для объектов созданных на стеке он вызовется автоматически как только выдете за пределы видимости.
1
19417 / 10034 / 2445
Регистрация: 30.01.2014
Сообщений: 17,697
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
12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,054
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
18124 / 10708 / 2063
Регистрация: 27.09.2012
Сообщений: 26,996
Записей в блоге: 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
19417 / 10034 / 2445
Регистрация: 30.01.2014
Сообщений: 17,697
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
19417 / 10034 / 2445
Регистрация: 30.01.2014
Сообщений: 17,697
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
19417 / 10034 / 2445
Регистрация: 30.01.2014
Сообщений: 17,697
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
19417 / 10034 / 2445
Регистрация: 30.01.2014
Сообщений: 17,697
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
Ответ Создать тему
Новые блоги и статьи
Вопросы на собеседованиях по микросервисам
ArchitectMsa 27.03.2025
Работодатели ищут не просто разработчиков, знающих базовые концепции, а специалистов, разбирающихся в тонкостях масштабирования, отказоустойчивости и производительности. Сейчас на первый план выходят. . .
Взаимодействие Python с REST API
py-thonny 27.03.2025
REST API - это архитектурный стиль взаимодействия компонентов распределённого приложения в сети. Python располагает функциональным набором инструментов для работы с REST API и основная библиотека для. . .
sshd restrictions, ssh access limitations
jigi33 26.03.2025
sshd restrictions | ssh access limitations рестрикции доступа на сервер sshd статья: https:/ / www. golinuxcloud. com/ restrict-allow-ssh-certain-users-groups-rhel
Компиляция C++ с Clang API
NullReferenced 24.03.2025
Компиляторы обычно воспринимаются как черные ящики, которые превращают исходный код в исполняемые файлы. Мы запускаем компилятор командой в терминале, и вуаля — получаем бинарник. Но что если нужно. . .
Многопоточное программировани­е в C#: Класс Thread
UnmanagedCoder 24.03.2025
Когда запускается приложение на компьютере, операционная система создаёт для него процесс - виртуальное адресное пространство. В C# этот процесс изначально получает один поток выполнения — главный. . .
SwiftUI Data Flow: Передача данных между представлениями
mobDevWorks 23.03.2025
При первом знакомстве со SwiftUI кажется, что фреймворк предлагает избыточное количество механизмов для передачи данных: @State, @Binding, @StateObject, @ObservedObject, @EnvironmentObject и другие. . . .
Моки в Java: Сравниваем Mockito, EasyMock, JMockit
Javaican 23.03.2025
Как протестировать класс, который зависит от других сложных компонентов, таких как базы данных, веб-сервисы или другие классы, с которыми и так непросто работать в тестовом окружении? Для этого и. . .
Архитектурные паттерны микросервисов: ТОП-10 шаблонов
ArchitectMsa 22.03.2025
Популярность микросервисной архитектуры объясняется множеством важных преимуществ. К примеру, она позволяет командам разработчиков работать независимо друг от друга, используя различные технологии и. . .
Оптимизация рендеринга в Unity: Сортировка миллиона спрайтов
GameUnited 22.03.2025
Помните, когда наличие сотни спрайтов в игре приводило к существенному падению производительности? Время таких ограничений уходит в прошлое. Сегодня геймдев сталкивается с задачами совершенно иного. . .
Образование и практика
Igor3D 21.03.2025
Добрый день А вот каково качество/ эффективность ВУЗовского образования? Аналитическая геометрия изучается в первом семестре и считается довольно легким курсом, что вполне справедливо. Ну хорошо,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер