Как подсчет ссылок интеллектуального указателя подсчета ссылок работает?

Я написал сценарий для решения этой проблемы. Его можно запустить как один из первых шагов сборки в конфигурации сборки TC. Сценарий будет запрашивать детали запроса запроса от Github, анализировать ответ и указывать имена источника и назначения в качестве параметров TeamCity и переменных среды. На следующих этапах сборки вы сможете прервать сборку или сделать все, что вам нужно, на основе этих переменных.

https://gist.github.com/dzzh/a6d8631e9617777fb5237bc9ec7b356b

Чтобы сценарий работал, вам нужно отправить идентификатор PR в качестве аргумента командной строки. Мы используем рекомендуемый refspec (refs / pulls / * / head) для запуска наших сборников, я извлекаю из него PR-идентификатор и вызывается скрипт с ним.

28
задан Srikanth 7 April 2009 в 11:12
поделиться

6 ответов

Я видел два различных ненавязчивых подхода к этому:

  1. Интеллектуальный указатель выделяет маленький блок памяти для содержания ссылочного счетчика. Каждая копия интеллектуального указателя затем получает указатель на фактический объект и указатель на подсчет ссылок.
  2. В дополнение к объектному указателю каждый интеллектуальный указатель содержит предыдущий и прямой указатель, таким образом, формируя двунаправленный связанный список интеллектуальных указателей к конкретному объекту. Подсчет ссылок неявен в списке. Когда интеллектуальный указатель копируется, он добавляет себя к списку. После разрушения каждый интеллектуальный указатель удаляет себя из списка. Если это - последнее в списке, это затем освобождает ссылочный объект также.

Если Вы идете сюда и прокручиваете к нижней части, существует превосходная схема, которая объясняет эти методы намного более ясно.

65
ответ дан Ferruccio 28 November 2019 в 02:36
поделиться

Каждый объект интеллектуального указателя содержит общее количество ссылок - по одному на каждый необработанный указатель.

Вы можете взглянуть на эту статью. Эта реализация хранит их в отдельном объекте, который копируется вокруг. Вы также можете взглянуть на документацию boost или на статью Wikipedia об умных указателях.

3
ответ дан Gabriel Southern 14 October 2019 в 09:56
поделиться

Многие ответы обращаются к способу хранения счетчика ссылок (он хранится в общей памяти для всех shared_ptr, которые содержат тот же собственный указатель), но большинство исключает проблему утечек.

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

Самым простым решением проблемы цикла является смешивание shared_ptr (указатели с подсчетом ссылок) со слабыми указателями, которые не разделяют владение объектом.

Общие указатели будут совместно использовать ресурс (указатель) и дополнительную информацию reference_count. Когда вы используете слабые указатели, счетчик ссылок удваивается: есть счетчик ссылок общего указателя и счетчик ссылок слабого указателя. Ресурс освобождается всякий раз, когда число общих указателей достигает 0, но информация reference_count остается активной до тех пор, пока не будет освобожден последний слабый указатель.

В двусвязном списке внешняя ссылка хранится в shared_ptr, а внутренние ссылки просто слабые. Всякий раз, когда нет внешних ссылок (shared_ptr), элементы списка освобождаются, удаляя слабые ссылки. В конце все слабые ссылки были удалены, и последний слабый указатель на каждый ресурс освобождает информацию reference_count.

Это менее запутанно, чем кажется вышеупомянутый текст ... Я попробую позже.

2
ответ дан David Rodríguez - dribeas 14 October 2019 в 09:56
поделиться

Нет. shared_ptr просто сохранить один дополнительный указатель для подсчета ссылок.

Когда вы копируете объект shared_ptr, он копирует указатель с количеством ссылок, увеличивает его и копирует указатель на содержащийся объект.

2
ответ дан bayda 14 October 2019 в 09:56
поделиться

Создание утечки памяти с интеллектуальными указателями подсчета ссылок очень легко. Просто создайте любую подобную графику структуру объектов, которая имеет цикл в графике. Объекты в цикле будут препятствовать друг другу быть выпущенными. Это не может быть разрешено автоматически - например, при создании двойного списка ссылок, необходимо заботиться о никогда удалении больше чем одного объекта за один раз.

3
ответ дан sharptooth 28 November 2019 в 02:36
поделиться

Насколько я помню, была проблема указателя подсчета ссылок, который рассматривают в главе Эффективного C++.

В принципе у Вас есть "легкий" класс указателя, содержа указатель на класс, содержащий ссылку, которая знает, чтобы увеличить/постепенно уменьшить ссылку и уничтожить объект указателя. Тот класс подсчета ссылок указывает на объект, на который сошлются.

2
ответ дан Cătălin Pitiș 28 November 2019 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: