Подтвердить что ты не робот

Weak_ptr, make_shared и освобождение памяти

Управляющий блок a shared_ptr сохраняется в живых, пока присутствует хотя бы один weak_ptr. Если общий указатель был создан с помощью make_shared, это означает, что вся память объекта сохраняется. (Сам объект правильно разрушен, но поскольку блок управления и память для объекта были выделены в одном фрагменте, как это делает make_shared, они могут быть освобождены только вместе.)

Правильно ли я понимаю?

Похоже, что это поведение представляет проблему, например, в знаменитом примере кеша. Память для объектов будет сохранена навсегда.

Это проблема в каких-то практических ситуациях? Должен ли shared_ptr создать конструктор в такой ситуации (большой объект и намерение использовать weak_ptr s)?

4b9b3361

Ответ 1

Правильно ли я понимаю?

Да. Если ваш weak_ptr значительно переживает (большой) объект, и вы сильно зажаты в памяти, может быть полезно избежать make_shared.

Однако "большой" здесь измеряется sizeof, и многие концептуально "большие" объекты (например, большинство стандартных контейнеров, кроме std::array) довольно малы по этой метрике, поскольку они выделяют дополнительную память для хранения их содержимое, которое будет освобождено, как только объект будет уничтожен.

Ответ 2

Я пробовал это в VS2013, и вы совершенно правы. Деструктор вызывается, когда последний shared_ptr уничтожается, поэтому любые другие объекты или память, связанные с объектом, будут уничтожены, но если shared_ptr создается с make_shared, память никогда не будет уничтожена до тех пор, пока не будет последним weak_ptr.

Я считаю, что всегда полезно очищать или reset ваши слабые_ptrs, если функция lock() терпит неудачу, потому что даже без make_shared она все еще использует некоторую память.