Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726

Повторный вызов деструктора

26.12.2020, 08:41. Показов 5474. Ответов 67

Студворк — интернет-сервис помощи студентам
Привет!
Есть класс TVector и есть у него деструктор вот такой:
C++ (Qt)
1
2
3
4
5
6
7
    ~TVector(void)
        {
            delete[] this->data;    // уничтожаем данные
            this->data = NULL;      // не оставляем висячих указателей
     
            this->n = 0;            // данных нет, поэтому кол-во элементов стало равно 0
        }
тут вроде все легко и все работает, но в условии задачи есть такое требование:
"надо корректно обрабатывать ситуацию повторного вызова деструктора. В этом случае деструктор не должен пытаться освобождать в динамической памяти объекты повторно"

я не оч.выкупил, что требуется, но решил добавить такую проверку в деструкторе:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
    ~TVector(void)
        {
            if(this->n != 0)
            {
                delete[] this->data;    // уничтожаем данные
                this->data = NULL;      // не оставляем висячих указателей
     
                this->n = 0;            // данных нет, поэтому кол-во элементов стало равно 0
            }
        }
Вопрос: это нужно было сделать с деструктором или нет?) Если нет, то, что??
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.12.2020, 08:41
Ответы с готовыми решениями:

Повторный вызов деструктора
{ bar b; b.~bar(); } В данном примере деструктор bar вызовется дважды. Как у уже удаленного объекта может вызываться...

Исключительные ситуации (повторный вызов деструктора)
Всем привет ! Подскажите пожалуйста , почему повторно вызываются деструкторы класса A,B,C? #include <stdio.h> #include...

Повторный вызов деструктора для объекта
Здравствуйте! К сожалению, я пока не умею пользоваться отладчиком для анализа работы программ, поэтому в очередной раз обращаюсь к вам...

67
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.12.2020, 14:43
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от FasterHarder Посмотреть сообщение
корректно обрабатывать ситуацию повторного вызова деструктора
корректно - никак.
сама формулировка - за гранью здравого смысла.

вызов деструктора - это смерть объекта.
после того, как деструктор отработал, объект - мёртв.

технически, "повторный запуск деструктора",
это - ситуация, когда итак уже мёртвый объект умирает ещё один раз.
ты осознаешь какой это бред?

0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
26.12.2020, 14:43
Цитата Сообщение от FasterHarder Посмотреть сообщение
а как можно исключить повторный вызов деструктора?
пример:
this->.~TClass();
this->.~TClass();
Не писать такой код.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.12.2020, 14:44
Цитата Сообщение от FasterHarder Посмотреть сообщение
this->data = NULL;      // не оставляем висячих указателей
this->n = 0;            // данных нет, поэтому кол-во элементов стало равно 0
вот эти записи в деструкторе - не нужны.
они избыточны.
твой объект умирает.
он все равно уже не воспользуется этими данными.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 14:49  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
ты осознаешь какой это бред?
конечно! именно по этой причине я пришел на форум))
если бы все было четко и ясно, то давно бы реализовал все без проблем.

меня вообще смутило, что в постановке задания докапываются до этого деструктора! у него одна цель: удалить дин.память. Зачем что-то еще морочить с ним)

Добавлено через 52 секунды
Цитата Сообщение от hoggy Посмотреть сообщение
он все равно уже не воспользуется этими данными.
конечно, он же уже мертв и не дышит или на последнем издыхании, т е делает последний выдох в своей жизни
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.12.2020, 16:01
Цитата Сообщение от FasterHarder Посмотреть сообщение
this->.~TClass();
this->.~TClass();
Цитата Сообщение от FasterHarder Посмотреть сообщение
как можно ЭТО исключить?
Очень просто. Вы НЕ должны писать ТАК.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 16:15
Цитата Сообщение от DrOffset Посмотреть сообщение
Вызовется.
Это я и имел ввиду
Цитата Сообщение от DrOffset Посмотреть сообщение
код будет содержать UB, а защита обнулением внутри деструктора от этого не спасет (UB от этого не исчезнет).
Об этом было говорено, но перехват исключения, хотя бы, это не краш от повторного освобождения. Но в принципе согласен. Все выделяемые попутно ресурсы тоже нужно аллоцировать в каком-то раз и навсегда выделенном буфере, например.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.12.2020, 16:18
Цитата Сообщение от FasterHarder Посмотреть сообщение
меня вообще смутило, что в постановке задания докапываются до этого деструктора! у него одна цель: удалить дин.память.
и правильно докапываются.

только ты не понял.
тебя никто не просит дважды убивать объект.
напротив, твоя задача: защитить код от ничайного "двойного умирания".

как вообще может так случиться, что объект помер дважды?

C++
1
2
3
4
5
6
7
8
9
10
struct some{};
 
some* ptr;
 
int main()
{
    ptr = new some;
    delete ptr;
    delete ptr; // <--- мы ничайно
}
что бы недопустимть UB, нужно:
- либо просто запретить второй вызов delete
- либо сделать так, что бы второй вызов delete не приводил к смерти объекта

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct some{};
 
some* ptr;
 
int main()
{
    ptr = new some;
    delete ptr;
    
    ptr = nullptr;
 
    delete ptr; // <--- уже не навредит
}
но! есть нюанс:
а что, если у нас многопоточная среда?
указатель ptr - глобальный,
а значит доступ к объекту могут получить несколько потоков.

что, если несколько потоков одновременно начнут убивать наш объект?

что бы гарантировать надежность кода,
нужно обеспечить thread-safe защиту для указателя ptr.

сделать это можно самыми разными способами.
есть убер-надежные и элегантные RAII.

я же приведу пример попроще:

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
#include <thread>
#include <mutex>
 
struct some {};
 
std::mutex mutex_ptr;
some* ptr;
 
void work()
{
    ::std::lock_guard<std::mutex> 
        lock(mutex_ptr);
    
    delete ptr; 
    ptr = nullptr; // <--- теперь безопасно
}
 
int main()
{
    ptr = new some;
    
    std::thread t1(work);
    std::thread t2(work);
    
    t1.join();
    t2.join();
}
итого:
тщательно осмыслив материал, ты ответишь своему преподавателю:

1.
указатели на динамическую память необходимо обнулять,
с целью предотвратить ущерб от ничайного двойного delete

2.
в многопоточной среде,
доступ к функциональности, способной убить объект,
должен осуществляться под защитой мутекса.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 16:44  [ТС]
что бы недопустимть UB, нужно:
- либо просто запретить второй вызов delete
- либо сделать так, что бы второй вызов delete не приводил к смерти объекта

C++
1
2
3
4
5
6
7
8
9
10
11
12
struct some{};
 
some* ptr;
 
int main()
{
    ptr = new some;
    delete ptr;
    
    ptr = nullptr;
 
    delete ptr; // <--- уже не навредит
------------------------
1. твой пример на указателе, я же работаю со статическими экземплярами класса и оператор дилит скрыт в деструкторе
2. ты жестко обнуляешь в конкретном месте программы птр, а при тесте это могут вбить в любом месте прогги

короче, я пока оставляю деструктор как есть

я вообще уже имею трактовку, что речь идет про разделяемую память между векторами и намекают на деструктор. Т е намек делается на то, что у каждого вектора дб свой участок памяти, а не общий и чтобы при вызове деструктора для одного объекта остальные объекты не разрушались
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 16:48
Деструктор работает с this а он не может быть сброшен. Он константа)
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.12.2020, 16:50
Цитата Сообщение от FasterHarder Посмотреть сообщение
такую проверку в деструкторе
Такая проверка на NULL в любом случае не нужна.

Обнуление можете оставить, чтобы удовлетворить требования преподавателя. Но вы должны понимать, что в реальной ситуации делать обнуление не требуется.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 16:52  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
что это в реальной ситуации делать
Макконел рекомендует ВСЕГДА это делать
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.12.2020, 16:57
Цитата Сообщение от FasterHarder Посмотреть сообщение
Макконел рекомендует ВСЕГДА это делать
Речь об обнулении полей в деструкторе. Макконел рекомендует обнулять поля в деструкторе? Вы уверены, что вы верно поняли, чтобы это утверждать?
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 16:59  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Макконел рекомендует обнулять
любые указатели после того, как они не используются/перестали быть нужны/удалены и пр.

дословно я не помню
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.12.2020, 17:04
FasterHarder, эта рекомендация касается объектов, время жизни которых еще не закончено, но логически они уже не используются. После выполнения деструктора время жизни всех полей заканчивается: их больше не существует и совершенно не важно какое у них значение, потому любое обращение несуществующему объекту приводит к UB.

Рекомендации Макконела - это очень хорошо, но если вы не можете различить ситуации, когда они применимы, а когда нет, то толку от них немного.
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
26.12.2020, 17:23
Цитата Сообщение от IGPIGP Посмотреть сообщение
Деструктор работает с this а он не может быть сброшен. Он константа)
Он не константа, а prvalue.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.12.2020, 17:42
Цитата Сообщение от 0x10 Посмотреть сообщение
this
Цитата Сообщение от 0x10 Посмотреть сообщение
Он не константа, а prvalue.
this - всегда константа.
категория доступа через this - всегда lvalue.

Добавлено через 3 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Макконел рекомендует обнулять поля в деструкторе?
не было такого.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.12.2020, 18:02
Цитата Сообщение от FasterHarder Посмотреть сообщение
твой пример на указателе
да.
потому что ты использовал волшебную фразу:
Цитата Сообщение от FasterHarder Посмотреть сообщение
дин.память
каждый раз, когда мы работаем с дин. памятью,
мы оперируем указателем.

Цитата Сообщение от FasterHarder Посмотреть сообщение
а при тесте это могут вбить в любом месте прогги
на языке с++ существует множество способов, как острелить себе яйца.
и при этом нет возможности реализовать защиту от дурака.

прочитав Макконелла, ты должен был понять,
что защиту нужно делать только от ничайных ошибок.
от откровенных вредителей,
и от дэбилов делать защиту бесполезно.




например,
один альтернативно одаренный человек решил запускать методы по нулевому указателю.
он - художник, он так видит.
как ты сможешь защить код от такого дэбила?

C++
1
2
3
4
5
6
7
8
9
10
struct some 
{
    virtual ~some(){}
    virtual void foo(){}
};
int main()
{
    some* ptr = nullptr;
    ptr->foo();  // <--- uppssss
}



Цитата Сообщение от FasterHarder Посмотреть сообщение
Т е намек
плохой ход.
"намеки" - это к гадалкам, к бабкам на лавочке, ну или просто к женщинам.
они любят намеки.

в программировании намёкам места нет.
если что-то не понятно - уточняй сабж у руководства.
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
26.12.2020, 18:06
Цитата Сообщение от hoggy Посмотреть сообщение
this - всегда константа.
Цитата Сообщение от hoggy Посмотреть сообщение
его действительно правомерно было бы называть константным.
однако это не так. он - prvalue (чисто временный, рожденный как временный объект)
Указатель this, теория
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.12.2020, 18:22
Цитата Сообщение от 0x10 Посмотреть сообщение
Указатель this, теория
действительно prvalue.
спасибо, что указал мне на мою ошибку.

странно, я вроде бы знаком с теорией.
https://rextester.com/QCYR71969

но все равно, уже не в первый раз наступаю на эти же грабли.
в голове почему то прочно засела мысль,
что this - не_изменяемый указатель.

хотя на самом деле this вообще, строго говоря, указателем не является.
это - выражение.

что-то наподобие такого:
C++
1
template<class t> T* this();
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 21:34
Цитата Сообщение от 0x10 Посмотреть сообщение
Он не константа, а prvalue.

0x10, спасибо))) Я давно хочу написать короткое эссе о прикладом математизме в предметной области. Я постоянно пишу об этом, но как сказал поэт:
Трудно петь о горах,
Если знаешь, что спето немало,
Но труднее не петь,
Если знаешь, что спето не всё
Вначале было значение, и значение было у ссылки, и значение было ссылка.
Ибо сказано: I am - Pointer!
Историю о ссылках и категориях значений от времен язычествая зыка С я предлагаю посмотреть тут:
https://en.cppreference.com/w/... e_category
Размывание границ первоначально очерченных абстракции - путь из знания в религию. Часто можно видеть, как молодой послушник получив очередное наставление с сакральным знанием, в экстазе восклицает
"О спасибо тебе брат мой! Я слышу Голос! "
А в ответ
Чиста твоя вера брат и рвение твоё похвально. Но у prvalue нет голоса. Ты ещё многое узнаешь, -юный падаван.
Так и живём.
От себя добавлю:
Each C++ expression (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a type and a value category.
То есть this как и много другое, в зависимости от контекста, это
- английское слово
- ключевое слово языка
- выражение имеющее категорию значения
- программный объект имеющий тип
Вот ещё ссылка
https://www.ibm.com/support/kn... plr035.htm
в частности
The type of the this pointer for a member function of a class type X, is X* const. If the member function is declared with the const qualifier, the type of the this pointer for that member function for class X, is const X* const.
IBM - фирма, которую мы знаем по многим штуковинам начиная от процессоров и заканчивая серверами. В основе MS-DOS (и др. OS) лежит IBM-DOS и биос-расширения. И то что мы знаем - вершинка айзберга, работающего на заказы минобороны USA и NASA. У этих людей нет времени на песнопения и хождения с хоругвями.
Хотелось бы добавить, что в моей коротенькой фразе
Цитата Сообщение от IGPIGP Посмотреть сообщение
Деструктор работает с this а он не может быть сброшен. Он константа)
Смысл вполне ясен и уточнения не требует.
Сказанное мною, - сказано не в обиду, а скорее от избытка чувств)
Поздравляю, всех вас с наступающим Новым Годом, братия во крестах!!!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.12.2020, 21:34

Вызов деструктора
Здравствуйте ,подскажите пожалуйста ,есть вот такой код ... При создании объекта MyClass в функции Foo() ,объект уничтожается когда мы...

Вызов деструктора
Вызывается ли деструктор объекта при завершении программы? а при аварийном завершении? А если снять процесс приложения диспетчером?

Вызов деструктора
Доброго вам времени суток. Проблема в том, что деструктор не выводит сообщение без этой строки. s1.~Shave(); И я не уверен, что так...

Вызов деструктора
Есть написанный мною код: #include &lt;iostream&gt; class Foo { private: int *key; public: Foo (const int a=0) { key = new int...

Вызов деструктора
При ручном вызове деструктора, освобождается ли память*


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Просветление в 5 секунд
kumehtar 10.07.2026
Андрей Веретенников выдал фразу недавно: "Вам не обязательно кем-то себя считать"
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru