Я что-то упускаю из общих / слабых указателей:
Когда shared_ptr
построен с использованием make_shared
используется только одно выделение памяти (для выделения памяти для блока управления и самого объекта). Что происходит, когда в последний раз shared_ptr
разрушен, но есть weak_ptr
осталось? В этот момент управляемый объект должен быть освобожден. Но если память выделена make_shared
освобождается, что делает слабые указатели недействительными, так как такое же освобождение разрушит контрольный блок.
С make_shared
а также allocate_shared
есть только один единственный контрольный блок управления, который содержит сам объект. Это выглядит примерно так:
struct internal_memory_type
{
unsigned char[sizeof T] buf; // make sure the object is at the top for
// efficient dereferencing!
// book keeping data
} internal_memory;
Объект строится на месте: ::new (internal_memory.buf) T(args...)
,
Память на весь блок выделяется ::operator new
или в случае allocate_shared
с распределителем allocate()
функция.
Когда объект больше не нужен, деструктор вызывается на самом объекте, что-то вроде internal_memory.buf->~T();
, Когда контрольный блок управления больше не нужен, то есть, когда исчезли все слабые ссылки, а также все сильные, блок контрольного управления в целом освобождается с помощью ::operator delete
или с распределителем deallocate()
функция для allocate_shared
,
Других решений пока нет …