2013-08-28 4 views
3

я пропускаю что-то об общих/слабых указателях:C++ 11: Как объект удален, если он был построен с использованием make_shared

Когда shared_ptr строится с помощью make_shared, используется только один выделение памяти (для выделения памяти для блока управления и самого объекта). Что произойдет, если последний shared_ptr уничтожен, но есть weak_ptr -s left? На этом этапе управляемый объект должен быть освобожден. Но если память, выделенная make_shared, будет освобождена, это сделает недопустимыми слабые указатели, поскольку такое же освобождение приведет к уничтожению блока управления.

+1

20.7.2.2.6/6: Замечания: Реализации поощряются, но не требуются *, для выполнения не более одной памяти . (Emphasis mine.) – cHao

ответ

8

С 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; 

Объект constucted на месте: ::new (internal_memory.buf) T(args...).

Память для всего блока выделяется ::operator new, или в случае allocate_shared с функцией распределителя allocate().

Когда объект больше не нужен, деструктор вызывается на самом объекте, что-то вроде internal_memory.buf->~T();. Когда блок контрольного управления больше не нужен, т. Е. Когда все слабые ссылки исчезли, а также все сильные, блок контрольного управления в целом освобождается ::operator delete или с функцией deallocate() распределителя для allocate_shared.

+0

Итак, когда общий счетчик указателей обращается в ноль, память объекта может быть не сразу освобождена, вызывается только деструктор? – user2052436

+0

@ user2052436: Естественно :-) –

+1

еще один вопрос: это означает, что если есть цикл слабых указателей, память будет потребляться в течение всего срока службы программы, даже если нет общих указателей слева? – user2052436