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

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

26.12.2020, 08:41. Показов 5478. Ответов 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
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
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
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
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
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
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
Ответ Создать тему
Новые блоги и статьи
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
Просветление в 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
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru