← Назад ко всем вопросам

Сколько памяти выделяется при создании функции с shared_ptr

1️⃣ Как кратко ответить

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

2️⃣ Подробное объяснение темы

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

  1. Сам объект shared_ptr: Это структура, которая содержит указатель на объект, которым она управляет. Размер этого объекта обычно равен размеру обычного указателя, то есть 4 байта на 32-битной системе и 8 байт на 64-битной системе.

  2. Управляющий блок: Это дополнительная структура, которая хранит:

    • Счетчик сильных ссылок (количество shared_ptr, указывающих на объект).
    • Счетчик слабых ссылок (количество std::weak_ptr, указывающих на объект).
    • Указатель на функцию удаления (если используется кастомный делетер).
    • Возможно, другие данные, зависящие от реализации.

Управляющий блок обычно выделяется в динамической памяти и его размер зависит от реализации стандартной библиотеки, но он может занимать несколько десятков байт.

Пример кода с комментариями:

#include <iostream>
#include <memory>
​
class MyClass {
public:
    MyClass() {
        std::cout << "MyClass Constructor" << std::endl;
    }
    ~MyClass() {
        std::cout << "MyClass Destructor" << std::endl;
    }
};
​
int main() {
    // Создаем shared_ptr, который управляет объектом MyClass
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    // std::make_shared выделяет память для объекта MyClass и управляющего блока
​
    {
        // Создаем еще один shared_ptr, указывающий на тот же объект
        std::shared_ptr<MyClass> ptr2 = ptr1;
        // Счетчик ссылок увеличивается, но дополнительная память не выделяется
    }
    // ptr2 выходит из области видимости, счетчик ссылок уменьшается
​
    // Когда последний shared_ptr (ptr1) выходит из области видимости,
    // вызывается деструктор MyClass и освобождается память
    return 0;
}
  • std::make_shared<MyClass>() создает объект MyClass и управляющий блок в одной операции, что может быть более эффективным, чем отдельное выделение памяти для объекта и управляющего блока.
  • ptr1 и ptr2 делят один и тот же управляющий блок, поэтому при создании ptr2 дополнительная память не выделяется.
  • Когда последний shared_ptr выходит из области видимости, вызывается деструктор объекта, и память освобождается.

Использование std::shared_ptr позволяет безопасно управлять временем жизни объектов, избегая утечек памяти и обеспечивая автоматическое освобождение ресурсов.

Тема: Умные указатели / Владение
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки