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

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

26.12.2020, 08:41. Показов 5586. Ответов 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
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 12:50  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
лишние действия
с этим я не спорю), но заявлять, что мой деструктор был полностью бессмысленным нетактично)
хотя ладно, тут даже нечего обсуждать, пусть будет по-твоему - не принципиально

Хотелось бы получить окончательное резюме и закрыть тему.
Но как я понимаю, что все норм было изначально. Наверное)

а что задание. Соорудить класс одномерный массив и перегрузить его по максимуму + все возможные конструкторы и все.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 12:52
Цитата Сообщение от 0x10 Посмотреть сообщение
Я не понимаю, что означает «placement new будет на другом объекте».
То что на каждом объекте будет вызван свой деструктор. Не будет повтора с формальной точки зрения. Но. 0x10, когда я впервые узнал что реинициализация старой памяти вызовом деструктора и плейсмента создаёт Новый объект, я спорил до хрипоты, плакл и даже бодался. Забили цитатами из стандарта. То есть, в душЕ я с вами) А комететчики в дУше.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.12.2020, 12:53
Цитата Сообщение от FasterHarder Посмотреть сообщение
с этим я не спорю), но заявлять, что мой деструктор был полностью бессмысленным нетактично)
Я вроде и не говорил, что полностью. Одна строчка точно была осмысленной.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 12:54  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Одна строчка точно была осмысленной.
как минимум 4ре, хотя С++ допускает все записать в одну строку, таки да, ты мне сможешь доказать, что только 1а строка имела смысл
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.12.2020, 12:55
Цитата Сообщение от FasterHarder Посмотреть сообщение
Хотелось бы получить окончательное резюме и закрыть тему.
Резюме - в деструкторе бесполезно делать защиту от повторного вызова. Поэтому в нём её делать не надо.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 13:06
Цитата Сообщение от FasterHarder Посмотреть сообщение
прожка у меня не падает вообще,
Так вы же защитились от поломки кучи и снизили вероятность падения. Хотя не всё что выполняется при вызове деструктора, это то что вы пишете в деструктор. Система та генерит ещё что-то. Вот это
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Если они есть, то в самом деструкторе уже бесполезно от этого защищаться, там будет куча других проблем
об том.
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну а ФУНДАМЕНТАЛЬНО - ты можешь заниматься в деструкторе любым идиотизмом.
Исключения выбрасывать. С формальной точки зрения, если есть исключение, то когда объект выходит из употребление, то исключение можно тоже выбросить. Это да)

Добавлено через 5 минут
oleg-m1973, чтобы мы не говорили о "разных" объектах в одной памяти но мысль 0x10, мне хочется проверить. Представь что вручную вызван деструктор, а плейсмент нью кинул экзепшн. При выходе из области будет повторный вызов деструктора или нет? Если гарантировано, - нет, то мы тут правы и защита не нужна. А если не гарантировано? Тогда всё плохо кончится.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 13:08  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Так вы же защитились от поломки кучи и снизили вероятность падения.
а как именно я защитился? что вы имеете в виду?
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 13:10
Цитата Сообщение от FasterHarder Посмотреть сообщение
что вы имеете в виду?
проверка - триггер со сбросом указателя и проверкой указателя на ноль.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 13:10  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Исключения выбрасывать.
кстати, очень точно подмечено!
программка должна все обрабатывать на исключениях. Я не стал говорить это сразу, т к не посчитал это нужным)
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.12.2020, 13:19
Цитата Сообщение от IGPIGP Посмотреть сообщение
oleg-m1973, чтобы мы не говорили о "разных" объектах в одной памяти но мысль 0x10, мне хочется проверить. Представь что вручную вызван деструктор, а плейсмент нью кинул экзепшн. При выходе из области будет повторный вызов деструктора или нет? Если гарантировано, - нет, то мы тут правы и защита не нужна. А если не гарантировано? Тогда всё плохо кончится.
Лично предпочитаю считать все деструкторы помеченными как noexcept (по-моему, так и есть, но, в любом случае, мне так лучше спится), поэтому стараюсь делать так чтоб исключений в них не было. Ну а повторного вызова тела деструктора не будет по-любому. Либо исключение возникнет в нём, либо после.

Добавлено через 6 минут
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Представь что вручную вызван деструктор, а плейсмент нью кинул экзепшн
У как ручной вызов деструктора связан с вызовом констуктора, т.е. с плейсмент нью? Ну и заботится о том, что твой объект будет удаляться вручную, да ещё криво, абсолютно неблагодарная задача. Не существует защиты от идиотов.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 13:19
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Лично предпочитаю считать все деструкторы помеченными как noexcept (по-моему, так и есть, но, в любом случае, мне так лучше спится), поэтому стараюсь делать так чтоб исключений в них не было.
Про исключение в деструкторе это стёб был. А то что ты процитировал, относится к конструктору (плесмент его вызовет), а в нём сам бог велел выделять ресурсы и кидать исключения.
Ещё раз
C++
1
2
3
4
5
6
7
8
{
ClassResorsesOwner obj(args...); //выделил
//поработал
obj.~ClassResorsesOwner (); очистился
new (&obj)  ClassResorsesOwner (otherArgs...); //tgrow!!!
 
 
//тут вызовется ~ClassResorsesOwner () ?? автоматом ??
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.12.2020, 13:23
Цитата Сообщение от IGPIGP Посмотреть сообщение
Ещё раз
Ну, тупо не нужно так делать и всё. Как я уже говорил
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну и заботится о том, что твой объект будет удаляться вручную, да ещё криво, абсолютно неблагодарная задача. Не существует защиты от идиотов.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.12.2020, 13:23
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Не существует защиты от идиотов.
oleg-m1973, вот тут не нужно обобщать. Не все такие как я. Есть же и умные люди. Они бывает пользуются пулами памяти выделяемой отдельно, а инициализируемой - отдельно. Не всегда RAII это хорошо (повторное выделение на куче мелких объектов - медленно).
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.12.2020, 13:33
Вернее, защита от идиотов слишком дорого стоит

Добавлено через 4 минуты
Цитата Сообщение от IGPIGP Посмотреть сообщение
oleg-m1973, вот тут не нужно обобщать. Не все такие как я. Есть же и умные люди. Они бывает пользуются пулами памяти выделяемой отдельно, а инициализируемой - отдельно.
Да я не обобщаю. Просто "умные люди" обычно вызывают деструкторы вручную только для неинициализированной памяти, массива байтов, для которой они перед этим вызвали placement new. В иных случаях пользуются move-copy конструкторами. Как раз для того, чтоб деструктор не был вызван дважды.

Добавлено через 4 минуты
С таким же успехом можно делать защиту от двойного вызова конструктора. Это ж не си-шарп, здесь можно много всякой хрени сделать. Но можно и не делать.
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,833
26.12.2020, 14:01
Цитата Сообщение от IGPIGP Посмотреть сообщение
Тут ломается гарантия того, что в программе не может быть 2-х разных объектов с различными адресами, но комитетчиков это не волнует.
Не ломается. Потому, что там есть еще слово "одновременно".

Добавлено через 3 минуты
Цитата Сообщение от FasterHarder Посмотреть сообщение
прожка у меня не падает вообще
Это не является в С++ достаточным условием, чтобы считать, что в программе нет ошибок.

Добавлено через 2 минуты
Цитата Сообщение от FasterHarder Посмотреть сообщение
Но как я понимаю, что все норм было изначально.
Норм или не норм, зависит от того как вы этот деструктор собрались применять.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 14:03  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Норм или не норм, зависит от того как вы этот деструктор собрались применять.
хорошее уточнение
поскольку деструктор вызывается АВТОМАТИЧЕСКИ, то вручную никак + мне еще раньше пояснил один спец, что даже при перегрузке операции присваивания деструктор вручную не вызывается

ответ: получается вручную НИГДЕ не планирую. А разве надо?)
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,833
26.12.2020, 14:16
Цитата Сообщение от IGPIGP Посмотреть сообщение
тут вызовется ~ClassResorsesOwner () ?? автоматом ??
Вызовется.
Если мы пишем такой код, то мы должны гарантировать, что исключений в конструкторе, который вызовется при выполнении placement new не будет. Если же этого не гарантировать, то код будет содержать UB, а защита обнулением внутри деструктора от этого не спасет (UB от этого не исчезнет).

Добавлено через 7 минут
Цитата Сообщение от FasterHarder Посмотреть сообщение
получается вручную НИГДЕ не планирую. А разве надо?)
Если не знаете зачем, значит не надо.
И тогда получается, что если вручную вызывать не надо, то в вашем деструкторе часть операций лишняя. Т.е. достаточно так:
C++
1
2
3
4
    ~TVector(void)
    {
        delete[] this->data;    // уничтожаем данные
    }
1) Вы можете проверить data на NULL, но это уже делается внутри delete[] (точнее delete[] гарантированно корректно ведет себя при передаче ему NULL-указателя), поэтому проверка не имеет смысла.
2) Вы можете обнулить поля, после вызова delete[], но в программе не может быть корректной ситуации, когда это обнуление сыграет какую-либо роль. Да, при вызове placement new и генерации исключения в нем, и если внутри конструктора не успели еще задать для data какое-то отличное от NULL значение, то в деструкторе, при наличии обнуленного заранее data, вы не упадете, но это не решит проблему, а только замаскирует ее. Если в программе есть проблема, но программа никак об этом не сообщает, то это очень плохо.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 14:20  [ТС]
DrOffset, а по самому стартовому вопросу в сообщении №1 можете что-то дополнить ключевое?
на данный момент получается, что то требование (СИНИМ выделено в 1 сообщении) является бессмысленным? или все-таки нет?
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,833
26.12.2020, 14:26
Цитата Сообщение от FasterHarder Посмотреть сообщение
Вопрос: это нужно было сделать с деструктором или нет?) Если нет, то, что??
Надо написать программу так, чтобы повторный вызов деструктора был невозможен.

Цитата Сообщение от FasterHarder Посмотреть сообщение
"надо корректно обрабатывать ситуацию повторного вызова деструктора. В этом случае деструктор не должен пытаться освобождать в динамической памяти объекты повторно"
Это условие не совсем точно сформулировано. Корректнее так:
надо корректно обрабатывать ситуацию повторного вызова деструктора. В этом случае программа должна быть написана так, чтобы исключить повторный вызов деструктора


Если же ваш преподаватель (или кто это задание дал) имел в виду именно первоначальную формулировку, то ему, наверное, стоит подучить С++. Вы, естественно, не сможете никак на это повлиять, и вам придется оставить ваш вариант и сдать ему. Но в голове вы должны держать, что все это сделано только ради оценки, а вы должны потом пойти и разобраться как нужно было делать правильно.
0
383 / 280 / 112
Регистрация: 28.04.2015
Сообщений: 1,726
26.12.2020, 14:38  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
чтобы исключить повторный вызов деструктора
а как можно исключить повторный вызов деструктора?
пример:
this->.~TClass();
this->.~TClass();

можно продолжить при желании и даже зациклить)

как можно ЭТО исключить?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.12.2020, 14:38

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера 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 (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru