Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
2 / 1 / 1
Регистрация: 15.09.2025
Сообщений: 49

Решить задачу "висячих" указателей

15.09.2025, 20:11. Показов 5077. Ответов 98

Студворк — интернет-сервис помощи студентам
Добрый день.

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

Как это можно реализовать? ... хотя бы общие идеи?

Спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.09.2025, 20:11
Ответы с готовыми решениями:

нужно решить задачу в ассемблере с комментами , срочно!
1. В регистр BL записать число EF, в ячейку со смещением 20 записать число 2A. Из содержимого BL...

Помогите решить задачу алгоритм есть
Дана блок-схема алгоритма обработки двумерного массива. Какова будет сумма элементов массива после...

Помогите решить задачу пожалуйста!!!
Элементы 3 строки поменять на минимальный элемент главной диагонали (матрица 4*4). Нужно составит...

98
110 / 74 / 6
Регистрация: 08.08.2025
Сообщений: 716
16.09.2025, 19:20
Студворк — интернет-сервис помощи студентам
И сразу стрелки перевел.

Конечно, СЛОЖНАЯ тема. Все пояснили уже. Зачем спрашивать дальше
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.09.2025, 19:39
Цитата Сообщение от JordanO2 Посмотреть сообщение
Мы обсуждаем сложную техническую тему
Какую?
Передать указатель и гарантировать что объект по этому указателю существует(или нет) может лишь программист.
В рамках своего кода.
ТЗ как такового нет. Ничего мы(и вот правильное использование местоимения) тут не обсуждаем.

Добавлено через 4 минуты
Тепер вернемся к нашим баранам.
Если использовать для владельца std::shared_ptr, который уже имеет функционал.
То можно передавать std::weak_ptr на владельца и это он уже будет гарантировать и давать возможность определить, существует ли исходный объект.
Это разумный компромисс.

Добавлено через 13 минут
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
#include <iostream>
#include <memory>
 
int main(){
   {
      int* ptr_ref = nullptr; // указатель, ваш КО
      {
         int owner = 100500;
         ptr_ref = &owner;
      }
      // ptr_ref - аисячий указатель, и опять я, КО
      if (!ptr_ref)
         std::cout << "Object expired" << std::endl;
   }
   
   {
      std::weak_ptr<int> ptr_ref;
      {
         auto owner = std::make_shared<int>(100500); // не указатель, но владелец объекта
         ptr_ref = owner;
      }
      // ptr_ref не указатель, но и не висячий
      if (ptr_ref.expired())
         std::cout << "Object expired" << std::endl;
   }
}
Так вот, в первом блоке фрагменте кода, никаким образом нельзя определить что указатель "висячий".
Это очевидно всем.

Во втором случае мы имеем возможность это определить, существует ли объект.
При этом с минимальными накладными расходами и без каких либо дополнительных приспособлений и телодвижений.

Теперь давай очередную "закидуху" из карманов, ТЗ то все равно нет, можно на ходу придумывать всё)
0
332 / 126 / 8
Регистрация: 19.07.2024
Сообщений: 664
16.09.2025, 20:52
Цитата Сообщение от JordanO2 Посмотреть сообщение
Всегда, везде, во ВСЕХязыках программирования ресурсы(объекты) очищает - владелец.
Потому и говорю, что вы - НАЧИНАЮЩИЙ. Или даже - ещё не начавший. Раз с таким апломбом утверждаете то, в чём не разбираетесь.
В Python объекты(ресурсы) очищает - сам Python.
Потому и сразу рекомендовал его вам.

PS: Но есть и другие языки, имеющие встроенные "сборщики мусора". Поинтересуйтесь у гугла. Это вам на домашнее изучение.
0
Модератор
Эксперт Java
 Аватар для alecss131
2894 / 1400 / 412
Регистрация: 11.08.2017
Сообщений: 4,482
Записей в блоге: 2
16.09.2025, 21:20
Цитата Сообщение от JordanO2 Посмотреть сообщение
ведь они в разы быстрее смартпоинтеров, а на некоторых задачах на порядок быстрее
Совершенно пустое заявление. Где доказательства? Умные почти не отличаются от сырых по скорости.

Добавлено через 1 минуту
Цитата Сообщение от jcxz Посмотреть сообщение
Но есть и другие языки, имеющие встроенные "сборщики мусора"
Не все языки сами управляющие жизнью объектов имеют сборщик мусора. Например есть Swift/Objective-C где нету ни ручного управления памятью ни сборщика мусора, за все отвечает ARC, который compile time.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.09.2025, 21:31
Цитата Сообщение от alecss131 Посмотреть сообщение
Например есть Swift/Objective-C где нету ни ручного управления памятью ни сборщика мусора, за все отвечает ARC, который compile time.
Можно небольшой пример на одном из этих ЯП. Где бы продлевалось или наоборот уменьшалось время жизни объекта (изменялось). Эти правила строго прописаны или есть возможность как то на это влиять?
0
Модератор
Эксперт Java
 Аватар для alecss131
2894 / 1400 / 412
Регистрация: 11.08.2017
Сообщений: 4,482
Записей в блоге: 2
16.09.2025, 21:50
SmallEvil, Я в этом плане плохо знаком. Они похожи на умные указатели в С++.
В языке только ссылки, они не могут быть нулевыми (nil), для этого в языке есть опционалы.
Ну там во первых все типы делятся на reference и value, те что value хранятся на стеке и всегда копируются (хотя можно параметр задать как inout и менять его копию), а другие в куче и передается только ссылка. Ссылки только у классов и замыканий (структуры это value тип), вот у них есть несколько видов ссылок, по умолчанию они все сильные (strong), есть еще слабые (weak) и бесхозные (unowned). Слабые всегда опционалы и требуют проверки на наличие значения и извлечения значения, а бесхозные неявные опционалы (автоматическое извлечение значения, можно нарваться на не валидную ссылку).
А так если есть хотя бы одна сильная ссылка то объект будет висеть, слабые и бесхозные ссылки не учитываются при удалении.
0
2 / 1 / 1
Регистрация: 15.09.2025
Сообщений: 49
17.09.2025, 06:32  [ТС]
Цитата Сообщение от alecss131 Посмотреть сообщение
Совершенно пустое заявление. Где доказательства?
alecss131,
извиняюсь, но хотелось бы общаться ближе к теме, т.к. офтопика тут уже 4 страницы...
Хотя, вижу от вас грамотные коменты, как исключение, отвечу:
Про доказательства(скорости указателей над смартами) - см. в любой официальной документации всегда упоминается, что смарты(из-за медлительности и ресурсоемкости) можно использовать ТОЛЬКО в случае необходимости(контролировать время жизни объекта), во всех остальных случаях, просто менять указатели на смарты - это расточительство.
-----------
Кстати(было тут #16), ТС может исправить заголовок темы? заменить бы слово "проблему" на "задачу", это возможно причина офтопика...

Цитата Сообщение от jcxz Посмотреть сообщение
В Python объекты(ресурсы) очищает - сам Python.
Вопрос ко всем,
кто-нибудь еще согласен с этим утверждением?
0
Модератор
Эксперт Java
 Аватар для alecss131
2894 / 1400 / 412
Регистрация: 11.08.2017
Сообщений: 4,482
Записей в блоге: 2
17.09.2025, 12:04
Цитата Сообщение от JordanO2 Посмотреть сообщение
в любой официальной документации
Без тестов все равно пустые слова. Да и что называть офф документацией? Есть только стандарты.
Цитата Сообщение от JordanO2 Посмотреть сообщение
кто-нибудь еще согласен с этим утверждением?
Да.

Я тут придумал интересный пример.
Возьмем за основу чистый Си, компилятор Clang и библиотеку Blocks. Напишем вот такой код
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 <stdio.h>
#include <Block.h>
 
typedef int (^IntBlock)();
 
IntBlock makeCounter(int start, int increment) {
    __block int i = start;
    return Block_copy( ^(void) {
        int ret = i;
        i += increment;
        return ret;
    });
}
 
int main(void) {
    IntBlock mycounter0 = makeCounter(0, 1);
    IntBlock mycounter1 = makeCounter(1, 2);
    printf("%d\n", mycounter0());
    printf("%d\n", mycounter1());
    printf("%d\n", mycounter0());
    printf("%d\n", mycounter1());
    printf("%d\n", mycounter0());
    printf("%d\n", mycounter1());
    Block_release(mycounter0);
    Block_release(mycounter1);
    return 0;
}
Перепишем его на Swift
Swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
typealias IntBlock = () -> Int
 
func makeCounter(start: Int, increment: Int) -> IntBlock{
    var i = start
    return { let ret = i
        i += increment
        return ret 
    }
}
 
let counter0 = makeCounter(start:0, increment: 1)
let counter1 = makeCounter(start:1, increment: 2)
print(counter0())
print(counter1())
print(counter0())
print(counter1())
print(counter0())
print(counter1())
Оба кода на выходе дадут
Code
1
2
3
4
5
6
0
1
1
3
2
5
Что вполне ожидаемо, так как замыкание захватывает переменную по ссылке и продлевает время жизни захваченных объектов, у каждой копии замыкания свои объекты.
Попробуем переписать это максимально точно на С++
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
#include <iostream>
#include <functional>
 
using IntBlock = std::function<int()>;
 
IntBlock makeCounter(int start, int increment){
    int i = start;
    return [&i, increment]{ int ret = i;
        i += increment;
        return ret;
    };
}
 
int main(){
    IntBlock counter0 = makeCounter(0, 1);
    IntBlock counter1 = makeCounter(1, 2);
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    return 0;
}
В голову приходит только такой вариант, но он не работающий, так как тут захваченный объект уничтожается после возврата из функции.
Единственное решение приходит только использовать сырые указатели
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
#include <iostream>
#include <functional>
 
using IntBlock = std::function<int()>;
 
IntBlock makeCounter(int start, int increment){
    int *i = new int{start};
    return [i, increment]{ int ret = *i;
        *i += increment;
        return ret;
    };
}
 
int main(){
    IntBlock counter0 = makeCounter(0, 1);
    IntBlock counter1 = makeCounter(1, 2);
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    return 0;
}
Но и тут возникает проблема, код работает и выдает нужный результат, но тут есть утечка памяти, даже 2. Как вот тут очистить память используя сырые указатели? При этом минимально изменив код.
В голову приходит только решение с использованием умных указателей. Хотя с их помощью не получается решить, не хватает знаний языка.
0
2 / 1 / 1
Регистрация: 15.09.2025
Сообщений: 49
17.09.2025, 12:21  [ТС]
Цитата Сообщение от alecss131 Посмотреть сообщение
Да и что называть офф документацией?
Вы же понимаете, о чем речь. Тем более было написано "в любой официальной документации"

Цитата Сообщение от alecss131 Посмотреть сообщение
используя сырые указатели?
И снова, уже второй раз, зачем указатели называть "сырыми" ?
0
Модератор
Эксперт Java
 Аватар для alecss131
2894 / 1400 / 412
Регистрация: 11.08.2017
Сообщений: 4,482
Записей в блоге: 2
17.09.2025, 12:27
Цитата Сообщение от alecss131 Посмотреть сообщение
Хотя с их помощью не получается решить, не хватает знаний языка.
Пытался использовать unique_ptr, не вышло, а вот с shared_ptr вполне
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
#include <iostream>
#include <functional>
 #include <memory>
 
using IntBlock = std::function<int()>;
 
IntBlock makeCounter(int start, int increment){
    auto i = std::make_shared<int>(start);
    return [i, increment]{ int ret = *i;
        *i += increment;
        return ret;
    };
}
 
int main(){
    IntBlock counter0 = makeCounter(0, 1);
    IntBlock counter1 = makeCounter(1, 2);
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    std::cout << counter0() << std::endl;
    std::cout << counter1() << std::endl;
    return 0;
}
Цитата Сообщение от JordanO2 Посмотреть сообщение
о чем речь
https://en.cppreference.com/w/... e_ptr.html
Прошу ткнуть носом, где написано про их медлительность
Цитата Сообщение от JordanO2 Посмотреть сообщение
зачем указатели называть "сырыми" ?
Тем что они сырые, ими никто не владеет и все надо делать руками. А просто указатели это общее понятие, включающее и умные.
https://learn.microsoft.com/en... w=msvc-170
1
2 / 1 / 1
Регистрация: 15.09.2025
Сообщений: 49
17.09.2025, 12:36  [ТС]
Цитата Сообщение от alecss131 Посмотреть сообщение
Тем что они сырые, ими никто не владеет
вы хотели сказать "они" не владеют, а не "ими" не владеют.
Согласны?
---------
Ура .... Raw pointers ... теперь вижу, откуда "сырые".
Спасибо за ссылку (learn.microsoft.com) - а вы спрашивали "что такое официальные доки"?
Но, ведь, microsoft - это ни капли НЕ стандарт.
Согласны?
0
Модератор
Эксперт Java
 Аватар для alecss131
2894 / 1400 / 412
Регистрация: 11.08.2017
Сообщений: 4,482
Записей в блоге: 2
17.09.2025, 12:45
Цитата Сообщение от JordanO2 Посмотреть сообщение
ткните меня носом
Вот, с моей же ссылки
In contrast, std::shared_ptr cannot be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete
Добавлено через 6 минут
Ссылки на cppreference
0
 Аватар для andrey_f
884 / 537 / 229
Регистрация: 21.02.2011
Сообщений: 5,705
17.09.2025, 12:54
Цитата Сообщение от alecss131 Посмотреть сообщение
Пытался использовать unique_ptr, не вышло, а вот с shared_ptr вполне
можно еще вот так сделать
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
#include <iostream>
#include <functional>
 
using IntBlock = std::function<int()>;
 
IntBlock makeCounter(int start, int increment) {
    return [i = start, increment]() mutable {
        int ret = i;
        i += increment;
        return ret;
    };
}
 
int main() {
    IntBlock counter0 = makeCounter(0, 1);
    IntBlock counter1 = makeCounter(1, 2);
    std::cout << counter0() << std::endl; // 0
    std::cout << counter1() << std::endl; // 1
    std::cout << counter0() << std::endl; // 1
    std::cout << counter1() << std::endl; // 3
    std::cout << counter0() << std::endl; // 2
    std::cout << counter1() << std::endl; // 5
    return 0;
}
0
2 / 1 / 1
Регистрация: 15.09.2025
Сообщений: 49
17.09.2025, 12:55  [ТС]
Цитата Сообщение от alecss131 Посмотреть сообщение
Вот, с моей же ссылки
да, про RAW pointer, я успел сам себя ткнуть носом, раньше чем вы это сделали
Спасибо

---------------
Кстати, а на этом cppreference.com есть какой-нибудь "About Us" ?
Не могу найти их причастность к "Комитету"
0
2 / 1 / 1
Регистрация: 15.09.2025
Сообщений: 49
17.09.2025, 13:13  [ТС]
Цитата Сообщение от JordanO2 Посмотреть сообщение
Кстати, а на этом cppreference.com есть какой-нибудь "About Us" ?
Не могу найти их причастность к "Комитету"
Сам спросил, сам нашел.
Оказывается, "комитет" знает про cppreference, но не признает их.

alecss131,
последняя просьба, как бесплатно скачать стандарт C++ с сайта isocpp.org ?
Они с меня деньги просят.
0
Модератор
Эксперт функциональных языков программирования
3140 / 2288 / 469
Регистрация: 26.03.2015
Сообщений: 8,898
17.09.2025, 14:16
Цитата Сообщение от JordanO2 Посмотреть сообщение
Как исправить заголовок темы?
Нажать кнопку "пожаловаться" (на стартовом сообщении) и описать ситуацию.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
17.09.2025, 14:37
Цитата Сообщение от JordanO2 Посмотреть сообщение
как бесплатно скачать стандарт C++ с сайта isocpp.org ?
Бесплатно можно только черновики.
Например: Document Number: N4950 (с++23)
C++ Standards Committee Papers

Цитата Сообщение от JordanO2 Посмотреть сообщение
Они с меня деньги просят.
Какие нехорошие дяди...
1
Модератор
Эксперт функциональных языков программирования
3140 / 2288 / 469
Регистрация: 26.03.2015
Сообщений: 8,898
17.09.2025, 14:54
Цитата Сообщение от SmallEvil Посмотреть сообщение
Наверное просто так там блоки using, финализаторы и ещё куча, чего я не знаю, разработано именно для этих целей.
Нет, не для этих. Это для освобождения прочих (не память) ресурсов.
0
Модератор
Эксперт функциональных языков программирования
3140 / 2288 / 469
Регистрация: 26.03.2015
Сообщений: 8,898
17.09.2025, 15:11
Цитата Сообщение от JordanO2 Посмотреть сообщение
На объект может ссылаться несколько указателей. Когда объект удаляется, то указатели не должны превратиться в "висячие". Их надо либо сразу обнулить, либо обнулять при первом обращении, или любой другой способ, чтоб избежать ошибки.
Вариант 1.
Работать с объектами и указателями на них через "фабрику". В ней запоминать выданные указатели и обнулять их при удалении объекта.

Вариант 2.
Хранить множество живых объектов (адресов). Перед использованием указателя проверять, что адрес содержится в множестве.

Вариант 3.
К каждому объекту добавлять заголовок. Перед использованием указателя анализировать содержимое заголовка.

Возможны и более узкоспециализированные решения, но для них требуется знание деталей (порядок использования объектов, язык программирования).
0
Модератор
Эксперт функциональных языков программирования
3140 / 2288 / 469
Регистрация: 26.03.2015
Сообщений: 8,898
17.09.2025, 15:23
Цитата Сообщение от a380 Посмотреть сообщение
Похоже автор пишет кривой код, а как собрать мусор, он не знает.
Вопрос был не про удаление объекта вообще и не про сборку мусора в частности. Вопрос был про указатели на удалённые объекты.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.09.2025, 15:23

помогите определить по какому алгоритму решить задачу
суть задачи состоит в том,что: есть 4 поля размерами 120га,95га,110га,140га..мне требуется...

Помогите решить задачу. Как расставить овец?
Не буду грузить техническими терминами типа 'смена ассортимента','конвеер'. Короче.. Волк с лисой...

Помогите решить задачу.
ПООМГИТЕ у меня завтра зачёт!!!! Короче такое вот заданеи: При решении данной задачи...

Помоготе решить задачу
Составить программу, которая выводит минимальное количество гирь, необходимых для взвешивания...

Помогите решить задачу по архитектуре ЭВМ
решите пожалуйста задачу x = (a*3+b*c)/(b-4) Пример x=(a*2+b*c)/(d-3) программа выполняет...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru