Ответ
Размер самого объекта std::shared_ptr<T> обычно равен двум указателям (например, 16 байт на 64-битной системе). Однако общие накладные расходы выше из-за динамически выделяемого блока управления (control block).
Структура:
- Указатель на управляемый объект.
- Указатель на блок управления. Этот блок содержит:
- Атомарный счетчик сильных ссылок (
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.