Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144

Как “научить” Указатель определять, что сам Объект уже удален?

30.08.2020, 22:14. Показов 4921. Ответов 40

Кажется, это называется “Висячий Указатель”, который указывает на уже удаленный Объект.
Хочется, чтоб когда Объект удаляется из памяти, то все указатели на него обращались бы NULL. Как это сделать?

М.б. существуют какие-то методики, чтобы бороться с Висячими Указателями?

Я уже отчаялся и пытаюсь придумать свой “велосипед” : типа менеджер Объектов, который регистрирует указатели и следит за удаляемыми объектами.
Но, надеюсь, что есть более простые способы.
Пожалуйста, подскажите...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.08.2020, 22:14
Ответы с готовыми решениями:

Что значит константный указатель на объект, указатель на константный объект, и как это можно использовать?
Подскажите, что значит константный указатель на объект, указатель на константный объект, и как это можно использовать??

Как проверить, быль ли удалён указатель или нет?
С похмелья голову заклинило %-) X* x=new X(); delete x; if(x) ? или как? Как проверить, удалён на данный момент указатель...

Нужно научить прогу определять дату
Здравствуйте тут есть такой вопрос, у меня имеется таблица stringgrid в которой в 1 столбце записаны даты, а за исключением 1 строчки везде...

40
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
31.08.2020, 15:14
Цитата Сообщение от Artem_Pv Посмотреть сообщение
серьезная задача
Безотносительно темы. Ты серьезно считаешь, что форум - это подходящий способ решать такие задачи? Кто потом будет отвечать за это решение?
Допустим даже я сейчас тебе накидаю пример, кто за последствия его применения будет в ответе, я или ты? Я тебе гарантий никаких не дам. Если уж у тебя не хватает квалификации выработать это решение самостоятельно, то лучше будет привлечь кого-то, кто даст эти гарантии. Это если задача и правда серьезная, а не ты ее такой хочешь представить. Просить "бесплатных" советов на форуме для серьезных задач - это чистая и незамутненная форма профанации.

Это я уж не касаюсь того, что в серьезных задачах всегда такое колоссальное количество нюансов, что скудным описанием на форуме точно не отделаешься.

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

Вот и что?

Поэтому общий ответ в силе: лечить надо причину.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
31.08.2020, 15:17
Цитата Сообщение от Artem_Pv Посмотреть сообщение
Еще жаль, что серьезная задача(OLAP-куб) обернулась в офф-топик.
Это всегда так бывает, когда дилетанты берутся решать серьёзные задачи. Вместо решения задачи, они, как правило, начинают воевать с какими-то придуманными ими же проблемами.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
31.08.2020, 15:19
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А зачем вообще здесь счетчик ссылок?
В смысле - "здесь"?
Я рассказал как устроен shared_ptr в ответ на этот вопрос.
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А как он это делает, есть идеи?
shared_ptr знает о других указателях потому, что ссылается на общую для всех указателей на конкретный объект память, в которой находится счетчик ссылок и сам (хранимый) объект. Посредством счетчика он узнает, нужно ли освобождать эту общую память и хранимый в ней объект, или нет.
1
фрилансер
 Аватар для Алексей1153
6494 / 5722 / 1133
Регистрация: 11.10.2019
Сообщений: 15,272
31.08.2020, 15:20
Artem_Pv, таки используй std::shared_prt , но в объект ещё добавь флажок deleted. Перед "удалением" из своего контейнера выставляй этот флажок. Если где-то есть указатели, они всегда смогут понять, что объект "удалён" и сами указатели можно почистить
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
31.08.2020, 15:27
Лучший ответ Сообщение было отмечено Artem_Pv как решение

Решение

Цитата Сообщение от Artem_Pv Посмотреть сообщение
Речь идет про динамический объект:
1. создаем Объект
2. присваиваем N указателей на Объект
3. удаляем Объект
4. (внимание)здесь нужно, чтоб эти N указателей обнулились
1) Общий на всю программу пул объектов.
2) Выделение и владение (это важно) происходит только в этом пуле, владеющий указатель сохраняется в спец. ячейку.
3) Наружу отдаются обертки с указателем на ячейку в пуле.
4) Всегда можно обратиться к ячейке в пуле и проверить жив объект или нет. Если пул сам обнулит ячейку, но она обнулится у всех ссылающихся на нее указателей.

Проблемы:
1) ячейка в пуле может быть перезанята, и проверка сломается;
2) можно не использовать ячейки повторно, или использовать их только по истечении какого-то времени (со всеми вытекающими из этого недостатками по расходу памяти);
3) сама ячейка всегда должна быть доступна для чтения, иначе вернемся к исходной проблеме.
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2020, 15:41
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Artem_Pv, таки используй std::shared_prt , но в объект ещё добавь флажок deleted. Перед "удалением" из своего контейнера выставляй этот флажок. Если где-то есть указатели, они всегда смогут понять, что объект "удалён" и сами указатели можно почистить
Бред.
std::shared_ptr освобождает память только если счетчик становится = 0, иначе просто ничего не делает кроме уменьшения счетчика.

Добавлено через 6 минут
DrOffset, Ну это по сути тоже что и gc писать или использовать пару shared+weak
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
31.08.2020, 15:43
Цитата Сообщение от Avazart Посмотреть сообщение
Ну это по сути тоже что и gc писать
В целом да.
0
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
31.08.2020, 15:44  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Проблемы:
1,2,3) ...
думаю, что не-проблема:
Когда требуется повторно использовать ячейки(уже удаленных объектов), то запускается процедура Упаковки всего пула, где перестраиваются внешние указатели на оставшиеся ячейки в пуле.
0
фрилансер
 Аватар для Алексей1153
6494 / 5722 / 1133
Регистрация: 11.10.2019
Сообщений: 15,272
31.08.2020, 15:46
Avazart, ты просто не вник. Это не влияние на указатели это пометка о невалидности объекта. И тогда, где-то, где есть указатель, можно проверить эту валидность и почистить указатель (понятно, что это не само произойдёт. а, так сказать, в пассивном режиме)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
{
    if(p)
   {
        if(p->deleted)
        {
            p.reset();
        }
        else
        {
              //работаем с объектом
              p->
        }
   }
}
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2020, 15:47
В любом случае придется указатели заменить объектами собственного класса(указателе-подобными) которые будут как говорит ТС "тяжелыми" ...

Иначе просто никак...
0
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
31.08.2020, 16:08  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
придется указатели заменить объектами собственного класса(указателе-подобными)
Обертка вокруг указателя - это м.б. объект, но лучше какая-нибудь легкая структура для оптимальности, главное, чтоб ее понимал менеджер пула объектов.

Цитата Сообщение от Avazart Посмотреть сообщение
будут как говорит ТС "тяжелыми" ...
ТС обнаружил, что "тяжелый" именно shared_prt, т.к. делает много лишней работы: подсчет ссылок, управление многопоточностью, т.е. это конечно полезно в других задачах, но не для текущей.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.08.2020, 16:29
Цитата Сообщение от Artem_Pv Посмотреть сообщение
- Занимают много места (под каждый указатель выделяют сложный объект)
- Медленно работают (подсчитывают ссылки, обеспечивают многопоточность, ...)
Цитата Сообщение от Artem_Pv Посмотреть сообщение
100 млн. “указателей”
Цитата Сообщение от Artem_Pv Посмотреть сообщение
указатели работают быстро и компактно. Программа летает и все хорошо
это примерно 762.94 mb
тут два варианта: либо на машине реально есть столько памяти,
либо нет, и тогда узким горлышком будет файл подкачки.

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

смарт-поинтер сам по себе узким горлышком не бывает.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2020, 16:33
Цитата Сообщение от Artem_Pv Посмотреть сообщение
но лучше какая-нибудь легкая структура для оптимальности
Чем Вам shared_ptr не легкая структура?

Добавлено через 1 минуту
Цитата Сообщение от Artem_Pv Посмотреть сообщение
ТС обнаружил, что "тяжелый" именно shared_prt, т.к. делает много лишней работы: подсчет ссылок, управление многопоточностью, т.е. это конечно полезно в других задачах, но не для текущей.
От подсчета ссылок не отказаться, касательно многопоточности можно реализовать свой shared_prt без атомиков.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.09.2020, 14:16
Цитата Сообщение от Avazart Посмотреть сообщение
В любом случае придется указатели заменить объектами собственного класса(указателе-подобными)
...
Цитата Сообщение от DrOffset Посмотреть сообщение
Наружу отдаются обертки с указателем на ячейку в пуле.
...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2020, 16:36
DrOffset, Акцент был на
Цитата Сообщение от Avazart Посмотреть сообщение
которые будут как говорит ТС "тяжелыми" ...
0
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
01.09.2020, 16:57
Лучший ответ Сообщение было отмечено Artem_Pv как решение

Решение

Artem_Pv, Объект помнит эти n указателей в списке и из своего деструктора их обнуляет. Указатели соответсвенно добавляются/удаляются из оного списка в своих конструкторах/операторах присваивания/деструкторахю Возможна реализация на основе односвязного списка с хранением указателя в самом смарте, как это сделано в итераторах STL. Так же и вариация на тему двусвязного списка с O(1) удалением смарта-подписчика.
В общем обширный список способов под общим названием "двунаправленные указатели". Если капать глубже - то одно из возможных реализаций/применений паттерна "обсервер".
1
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
02.09.2020, 06:01  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Объект помнит эти n указателей в списке и из своего деструктора их обнуляет.
Да, это хороший вариант, и очень простой.
Не нужно использовать управляющий движок(менеджер объектов).
Спасибо.
0
фрилансер
 Аватар для Алексей1153
6494 / 5722 / 1133
Регистрация: 11.10.2019
Сообщений: 15,272
02.09.2020, 08:19
это, получается, придётся хранить список указателей на указатели, ваще огонь И ни разу не оверхед. И просто то как!
0
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
02.09.2020, 11:24
Цитата Сообщение от Artem_Pv Посмотреть сообщение
Не нужно использовать управляющий движок(менеджер объектов).
Кстати если не нужно инстантное оповещение и/или нужно чтобы он никуда не делся пока его обрабатывают можно сделать на контроллерах на подобин shared/weak только с немного другим механизмом - т.е. удаляется объект не тогда когда счетчик жестких ссылок достиг нуля, а тогда когда он достиг нуля и флаг удалить поднят. Смарт реализующий композицию взводит флаг в своем деструкторе. Контроллер удаляется когда счетчик контроллеров достиг нуля. Смарт указывающий на пустой контроллер при локе сбрасывает и указатель на контроллер. Удаление же производится поднятием флага. При использовании двух видов смартов - аггрегация и композиция вполне работоспособно и для объектов не знающих о самой системе. Для таких правда нельзя организовать самоудаление - для этого объект должен знать контроллер и сам взводить флаг в контроллере, а не только смарт реализующий композицию.

Добавлено через 3 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это, получается, придётся хранить список указателей на указатели, ваще огонь И ни разу не оверхед. И просто то как!
ОВерхед будет в любом случае. Другой только вопрос по памяти (от 2x до 3х по размеру указателей для инстантного оповещения - что в общемто мелочи) и однократный по производительности при оповещении, или поcтоянно по прозизводительности на локи при каждом разыменовывании, и слегка меньший по памяти на хранение контроллеров, что гораздо гораздо менее приятно.
При этом список в принципе может быть односвязный и хранится указатель на следующего в самом смарте. С контроллерами все равно придется зранить два указателя - на объект и на контроллер.

Добавлено через 10 минут
Все в конечном итоге зависит от паттерна добавоения / удаления самтх указателей и того где более приемлем оверхед - по памяти или по производительности. К примеру у итераторов добавление/удаление в список производится строго в порядке первым добавлен/последни удален, а долгоживущих которые этим правилам не подчиняются или вообще нет или их мизер. Здесь оверхед на O(n) поиск в односвязном списке по производительности будет либо мизерным либо его вообще не будет, и соответсвенно можно слегка поэкономить память на второй связности списка. А если паттерн произвольный - то оверхед уже будет гораздо более значительный и гораздо логичнее добавить третий указатель на предыдущего в итератор, но получить удаление итератора из списка за O(1).
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2020, 12:39
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это, получается, придётся хранить список указателей на указатели, ваще огонь И ни разу не оверхед. И просто то как!
Я про это и говорил это куда "тяжелее" умного указателя получаться в котором только указатель на счетчик хранится.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.09.2020, 12:39

Основы: указатель на объект или объект, что выбрать?
Не до конца понимаю (или вообще не понимаю) когда лучше использовать указатель на объект, а когда объект. Например: // есть класс ...

Как двигать объект, когда нажимаешь на сам объект?
Здравствуйте, такая вот не приятная ситуация сам новичок в С# Хотел бы узнать как двигать обьект при прикосновении именно к нему а не...

Как преобразовать ссылку на объект в указатель на этот объект?
Как преобразовать ссылку на объект в указатель на этот объект? Буду благодарен за помощь.

Проверка удален ли объект
Здравствуйте, ни как не могу придумать как сделать проверку удален ли объект. На сцене есть объект, когда персонаж касается его он...

Удалить сочетание клавиш у ярлыка, который уже удален
Для каждого ярлыка на рабочем столе, через свойство можно задать сочетание клавиш (для быстрого вызова этого ярлыка). Но вот беда, ярлык...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
23. что сделано за последнее время.
anaschu 17.06.2026
• Эталон: Клиника НИИ питания РАМН, Москва — централизованный пищеблок, 225 коек, 180 пациентов • Git: репозиторий med2, ветка абсентеизм. Рабочий файл: СРесурсами1_v4. alp • Смежный проект:. . .
22. Подключение слоя системной динамики (потоковые диффуры): экономические метрики модели
anaschu 17.06.2026
Апдейт модели: финансовый контур, разделение затрат Продолжаю развивать модель рабочего коллектива на AnyLogic. В этот раз работа шла над агентом Экономика — финансовым SD-слоем модели. Задача:. . .
[golang] Insert Delete GetRandom O(1) (Leetcode: 380)
alhaos 16.06.2026
Insert Delete GetRandom O(1) Сложность: Medium Источник: LeetCode 380 Задача Реализовать структуру данных RandomizedSet, которая поддерживает следующие операции за O(1) в среднем:
Свет в конце тоннеля
kumehtar 16.06.2026
Поймал себя на одной мысли. Раньше мне всегда казалось неправильным жить без чёткого понимания, куда всё идёт. Будто я иду по дороге судьбы, но не знаю, куда она ведёт. А раз не знаю — значит,. . .
[golang] Реализация стека с поддержкой получения минимального элемента за O(1)
alhaos 16.06.2026
Min Stack Сложность: Medium Источник: LeetCode 155 Задача: Реализовать стек который поддерживает push, pop, top и получение минимального элемента за O(1). Методы:
[golang] Конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов.
alhaos 10.06.2026
Задача Реализовать конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов. Сигнатура func Fetch(urls string, maxConcurrent int) Result Пример urls :=. . .
[golang] Состояние гонки (race condition)
alhaos 10.06.2026
Состояние гонки (race condition) Состояние гонки (Race Condition) — это ошибка, возникающая при одновременном доступе нескольких горутин к одним и тем же данным без должной синхронизации. При этом. . .
Взрослые отношения, и почему они не получаются
kumehtar 09.06.2026
Когда в детстве ребёнок не получает от родителей чего-то важного, он лишается не просто приятных переживаний, а основы для формирования определённых внутренних качеств и навыков. Если ребёнок не. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru