В std::shared_ptr используется два счетчика:
shared_ptr, указывающей на тот же объект, и декрементируется при разрушении shared_ptr. Когда достигает нуля, объект, на который указывает shared_ptr, удаляется.std::weak_ptr из данного shared_ptr и декрементируется при разрушении weak_ptr. Когда достигает нуля, блок управления (control block), содержащий оба счетчика, удаляется.Эти счетчики хранятся в отдельном блоке управления (control block), который выделяется динамически при первом создании shared_ptr для объекта. Control block также может содержать deleter и allocator для объекта.
Использование атомарных счетчиков обеспечивает потокобезопасность при копировании и разрушении shared_ptr из разных потоков. Однако сам доступ к объекту, на который указывает shared_ptr, не потокобезопасен, если объект не является таковым изначально.
c