Как работает 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