Устраняет ли std:: weak_ptrs, когда выделенная память std:: make_shared освобождена?
Если я вызываю std::make_shared<T>
(а не просто выделяя shared_ptr<T>
явно), то я ожидаю, что подсчет ссылок будет выделен в памяти вместе с экземпляром T по соображениям производительности. Все хорошо и хорошо.
Но если у меня есть экземпляры weak_ptr
, ссылающиеся на один и тот же объект, вероятно, им понадобится доступ к этому счету ссылок, чтобы узнать, существует ли объект еще.
Итак, когда последний shared_ptr для экземпляра T уничтожается, наивное понимание системы подразумевает, что он не может освободить память, в которой хранится T, потому что weak_ptr все еще требуют доступа к этому счету.
Кажется, что существует отдельный слабый счетчик ссылок, и теоретически это может быть проведено отдельно от экземпляра T, так что T может быть уничтожен, а память освобождается, а слабые ссылки все еще существуют. Но потом мы вернулись к двум раздельным распределениям, превзойдя преимущества make_shared
.
Я предполагаю, что я что-то не понимаю. Как можно освободить память, выделенную для экземпляра, построенного с помощью std::make_shared
, при наличии слабых ссылок?
Ответы
Ответ 1
Если вы используете make_shared
, и если в реализации используется одно распределение как для объекта, так и для подсчета ссылок, то это распределение не может быть освобождено до тех пор, пока не будут освобождены все ссылки (как сильные, так и слабые).
Однако объект будет уничтожен после того, как будут выпущены все сильные ссылки (независимо от того, имеются ли еще слабые ссылки).
Ответ 2
Общая реализация заключается в том, что блок управления ref std::shared_ptr
содержит как сильный, так и слабый подсчет ссылок отдельно. Управляемый объект уничтожается, когда сильный счетчик ссылок обращается в нуль, но сам блок управления ref освобождается только тогда, когда слабый счетчик ссылок также достигает нуля.
(Когда вы используете std::make_shared
, сам блок управления ref содержит достаточно памяти для хранения управляемого объекта. Это всего лишь деталь.)
Другими словами, наблюдаемое поведение управляемого объекта не зависит от слабых указателей.