Разыменование значения r shared_ptr - PullRequest
7 голосов
/ 26 июня 2019

Я использую библиотеку, которая экспортирует такую ​​функцию, как:

// there is some type T
std::shared_ptr<T> foo(params);

, и хотя следующий код работает нормально:

auto p = foo(params);
auto & v0 = *p;
// use v0 as a T's reference

, происходит сбой ниже:

auto & v1 = *foo(params);
// use v1 as a T's reference

Так в чем же разница между v0 и v1?Большое спасибо за любую помощь.

Ответы [ 3 ]

9 голосов
/ 26 июня 2019

Объект, на который указывает shared_ptr, существует только до тех пор, пока существует хотя бы один общий указатель, который все еще указывает на него.

В вашем примере, скорее всего, толькоодин такой указатель, и он возвращается foo.

Для v0, p становится shared_ptr, сохраняющим объект живым.

Для v1 есть только временный общий указатель, который существует только на время инициализации v1.Указатель и объект, на который указывает указатель, исчезают к тому времени, когда вы используете ссылку, что делает его висящим в точке использования.

3 голосов
/ 26 июня 2019

Оператор

auto & v1 = *foo(params);

является потенциальным неопределенным поведением .

Функция foo, вероятно, создает внутри std::shared_ptr и возвращает его вызывающей стороне.как временный объект (технически prvalue ), который должен быть назначен некоторой переменной.

Вы не назначаете умный указатель вашего выражения какой-либо переменной.Однако вы берете объект, на который указывает (используя оператор *), и назначаете его для ссылки v1.

. В конце вычисления выражения временный std::shared_ptr будет уничтожен и (будучиумный указатель) объект также указывал.

Следовательно, auto & v1 ссылается на уничтоженный объект и доступ к нему является неопределенным поведением (в большинстве случаев вызывает ошибку сегментации).

1 голос
/ 26 июня 2019

В вашем первом примере, p остается в области видимости, сохраняя ссылку на объект и тем самым поддерживая его живым. Во втором примере shared_ptr уничтожается после создания v1, что уничтожает объект (при условии, что это была единственная ссылка), а v1 указывает на нераспределенную память.

...