@MayRiv

Что произойдёт после move-касте содержимого shared_ptr?

Добрый день! Кто может подробно объяснить происходящее в следующем коде? Я столкнулся в сегфолтом в недрах shared_ptr-а, и подозреваю следующий код в том, что он написан неправильно. Во-первых, я подозреваю, что нельзя кастить в rvalue содержимое shared_ptr, так как это может подменять память, на которую ссылается shared_ptr, и при обнулении счетчика ссылок будет вызван delete случайного куска памяти. Так ли это или я ошибаюсь?

Так же я считаю неправильным сохранение ссылки в классе T2 на объект T1 который мы передаём как rvalue, мне сложно обьяснить что произойдёт на самом деле, но это выглядит неправильно.

Надеюсь, кто-то сможет объяснить как будет работать следующий код, очень хочу разобраться
std::shared_ptr<T1> ptr = std::make_shared(new T1);
   auto  pResultElement = std::make_shared<T2>(std::move(*ptr));

class T2
{
public:
T2(const T1&& var):m_var(std::move(var)){}
private:
T1& var;
}
  • Вопрос задан
  • 503 просмотра
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
После move-каста содержимого shared_ptr мы говорим: объект под shared_ptr идёт на заклание, и в операциях перемещения мы можем потрошить его как угодно — лишь бы объект остался корректным. В данном коде (как я уже писал, он не компилируется) у нас одни ссылки, и не будет ровным счётом ничего: не выполнится ни одна операция перемещения.

Однако возможна такая ситуёвина, никак не связанная с временными ссылками. Во втором есть неуправляемая ссылка на первый — и при определённых условиях она может стать висячей.

Если в T2 всё-таки не ссылка, а экземпляр (T1 m_var), возможно, операция перемещения оставляет объект под ptr в некорректном состоянии, и деструктор ~T1() не может его уничтожить, или какая-то из операций над ptr не подозревает, что объект под ptr выпотрошен.

UPD. Что делает updateSearchResults? Только он может продлить время жизни объекта, сохранив где-то shared_ptr.

UPD2. Константная временная ссылка (const T&&) никакого смысла не несёт (по факту в STL пару раз используется). «Неизменный» и «можно выпотрошить» — это слегка противоречивые вещи.
И всё-таки я грешу на updateSearchResults, который сохраняет где-то объекты. Проблема может решиться, если в PoiSearchPlacesLocation ссылку заменить на shared_ptr. И — ВНИМАНИЕ — соответствующим образом подкорректировать сигнатуру конструктора. У shared_ptr есть конструктор, который берёт под управление любой объект-указатель, создавая новый счётчик, но хреново будет, если один и тот же объект управлять двумя разными счётчиками.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы