Как работает shared_ptr

`shared_ptr` — это интеллектуальный указатель, предоставляемый стандартной библиотекой. Основная его задача — управление динамически выделенной памятью с использованием подсчёта ссылок. Это позволяет нескольким указателям безопасно делиться одним объектом, автоматически освобождая ресурсы, когда они больше не нужны.

Принцип работы

1. Подсчет ссылок: Каждый `shared_ptr` содержит два основных элемента:

  • Указатель на управляемый объект.
  • Указатель на "control block" (блок управления), который содержит счетчик ссылок и, при необходимости, счетчик слабых ссылок (используется `weak_ptr`).

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

2. Удаление объекта: Когда последний `shared_ptr`, управляющий объектом, уничтожается (т.е. когда счетчик ссылок равен нулю), объект удаляется. Если блок управления также управляет деструктором объекта (обычно это так), то он также вызывается.

Пример:

```cpp
#include <iostream>
#include <memory>

struct Sample {
    Sample() { std::cout << "Sample Created\n"; }
    ~Sample() { std::cout << "Sample Destroyed\n"; }
};

int main() {
    {
        std::shared_ptr<Sample> sp1 = std::make_shared<Sample>();
        std::cout << "Счетчик ссылок: " << sp1.use_count() << std::endl;
        {
            std::shared_ptr<Sample> sp2 = sp1;  // Копирование shared_ptr
            std::cout << "Счетчик ссылок после копирования: " << sp1.use_count() << std::endl;
        }  // sp2 уничтожается, счетчик ссылок уменьшается
        std::cout << "Счетчик ссылок после уничтожения sp2: " << sp1.use_count() << std::endl;
    }  // sp1 уничтожается, счетчик ссылок равен нулю, объект удаляется
    return 0;
}
```

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

April 20, 2024, easyoffer