Назад к вопросам
Middle
84
questionbank
Как осуществляется подсчет ссылок в shared_ptr?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
shared_ptr использует внутренний управляющий блок (control block), который содержит счетчик сильных ссылок (strong count) и счетчик слабых ссылок (weak count).
Механизм работы:
- Создание: При создании первого
shared_ptr, указывающего на объект, создается управляющий блок с обоими счетчиками, инициализированными в 1.#include <memory> int main() { auto ptr = std::make_shared<int>(10); // Создается control block, strong_count = 1, weak_count = 1 (указатель в control block тоже считается) return 0; } - Копирование
shared_ptr: При копированииshared_ptrувеличиваетсяstrong_countв том же управляющем блоке.#include <memory> int main() { auto ptr1 = std::make_shared<int>(10); // strong_count = 1 auto ptr2 = ptr1; // strong_count увеличивается до 2 return 0; } - Присваивание
shared_ptr: Присваивание одногоshared_ptrдругому уменьшаетstrong_countу левого операнда (если он указывал на объект) и увеличиваетstrong_countу правого операнда. - Создание
weak_ptr: При созданииweak_ptrизshared_ptrувеличиваетсяweak_countв том же управляющем блоке.strong_countпри этом не меняется.#include <memory> #include <weak_ptr> int main() { auto ptr = std::make_shared<int>(10); // strong_count = 1, weak_count = 1 std::weak_ptr<int> weak_ptr = ptr; // weak_count увеличивается до 2 return 0; } - Выход из области видимости или сброс: При уничтожении
shared_ptr(например, при выходе из области видимости или вызовеreset()) уменьшаетсяstrong_count.#include <memory> int main() { { auto ptr = std::make_shared<int>(10); // strong_count = 1 } // strong_count уменьшается до 0 return 0; }#include <memory> int main() { auto ptr = std::make_shared<int>(10); // strong_count = 1 ptr.reset(); // strong_count уменьшается до 0 return 0; } - Освобождение объекта: Когда
strong_countстановится равным 0, объект, на который указывалshared_ptr, удаляется. - Освобождение управляющего блока: Когда и
strong_count, иweak_countравны 0, управляющий блок удаляется. - Выход из области видимости или сброс
weak_ptr: При уничтоженииweak_ptrуменьшаетсяweak_count.#include <memory> #include <weak_ptr> int main() { auto ptr = std::make_shared<int>(10); // strong_count = 1, weak_count = 1 { std::weak_ptr<int> weak_ptr = ptr; // weak_count = 2 } // weak_count уменьшается до 1 return 0; }
Подсчет ссылок является потокобезопасным благодаря атомарным операциям над счетчиками внутри управляющего блока.
Пример структуры управляющего блока (упрощенно):
struct ControlBlock {
std::atomic<long> strong_count{1};
std::atomic<long> weak_count{1}; // Изначально 1, так как control block хранит свой указатель
// Дополнительная информация, такая как deleter, allocator
};