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

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

26.12.2020, 08:41. Показов 5575. Ответов 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
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,832
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
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,832
26.12.2020, 16:50
Цитата Сообщение от FasterHarder Посмотреть сообщение
такую проверку в деструкторе
Такая проверка на NULL в любом случае не нужна.

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

дословно я не помню
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,832
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
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru