Сколько памяти занимает std::shared_ptr?

«Сколько памяти занимает std::shared_ptr?» — вопрос из категории Управление памятью, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Размер самого объекта std::shared_ptr<T> обычно равен двум указателям (например, 16 байт на 64-битной системе). Однако общие накладные расходы выше из-за динамически выделяемого блока управления (control block).

Структура:

  1. Указатель на управляемый объект.
  2. Указатель на блок управления. Этот блок содержит:
    • Атомарный счетчик сильных ссылок (use_count).
    • Атомарный счетчик слабых ссылок (weak_count).
    • Указатель на функцию-делитер (deleter).
    • (Опционально) Аллокатор.

Практический пример и сравнение:

#include <iostream>
#include <memory>

int main() {
    // Способ 1: make_shared (оптимизированное выделение)
    auto sp1 = std::make_shared<int>(42);
    // Объект и блок управления могут быть выделены одним блоком памяти.
    std::cout << "Size of shared_ptr object: " << sizeof(sp1) << " bytesn"; // e.g., 16

    // Способ 2: Конструктор от сырого указателя (менее эффективно)
    auto sp2 = std::shared_ptr<int>(new int(42));
    // Здесь два отдельных выделения: для int и для блока управления.

    // Для сравнения:
    std::unique_ptr<int> up(new int(42));
    std::cout << "Size of unique_ptr object: " << sizeof(up) << " bytesn"; // e.g., 8
    // unique_ptr не хранит счетчик ссылок, поэтому он легче.
    return 0;
}

Итог: shared_ptr — это инструмент с накладными расходами. В performance-critical коде я предпочитаю unique_ptr или слежу за созданием лишних копий shared_ptr.