Сброс слабого_птра влияет на shared_ptr?

11

Я не очень привык к использованию weak_ptrи столкнулся с довольно запутанной ситуацией. Я использую Intel XE 2019 Composer update 5 ( пакет 2019.5.281 ) в сочетании с Visual Studio 2019 ver. 16.2.5 . Я компилирую в 64-битной версии. Я использую стандарт C ++ 17 .

Вот код для моего решения спайка:

#include <memory>
#include <iostream>

using namespace std;

int main( int argc, char* argv[] )
{
    shared_ptr<int> sp = make_shared<int>( 42 );
    cout << "*sp = " << *sp << endl;

    weak_ptr<int> wp = sp;
    cout << "*sp = " << *sp << ", *wp = " << *wp.lock() << endl;

    wp.reset();
    cout << "*sp = " << *sp << endl;

    return 0;
}

Результат, который я ожидал получить:

*sp = 42
*sp = 42, *wp = 42
*sp = 42

... но вот что я получил:

*sp = 42
*sp = 42, *wp = 42
*sp = -572662307

Что происходит? Это нормально для того, shared_ptrчтобы быть измененным / недействительным, когда / связанный weak_ptrсброшен? Я немного смущен результатами, которые я получил. Честно говоря, я не ожидал этого результата ...

РЕДАКТИРОВАТЬ 1

В то время как ошибка возникает в 64-битной конфигурации, она не в 32-битной . В этой более поздней конфигурации результат является ожидаемым.

РЕДАКТИРОВАТЬ 2

Ошибка возникает только в Debug . Когда я встраиваю Release , я получаю ожидаемый результат.

dom_beau
источник
2
Я думаю, что ваша реализация имеет ошибку. GCC дает правильные результаты
NathanOliver
1
Невозможно воспроизвести в Visual Studio 2019 (v. 16.2.5)
Frodyne
1
Нет, это определенно не нормально.
причудливый
4
В случае, если это помогает отладке, -572662307 = 0xDDDDDDDDкоторая является способом msvc указывать освобожденную память кучи
Эрик

Ответы:

2

Похоже, что это реальная ошибка на стороне Intel ICC; Я сообщил об этом.

Еще раз спасибо за помощь в определении этой проблемы.

dom_beau
источник
1
Не могли бы вы добавить ссылку на отчет об ошибке в своем ответе? Таким образом, любой пользователь с той же проблемой может быть направлен в отчет об ошибке по его статусу.
Сандер Де
Я скорее добавлю комментарий, как только дело будет исправлено.
dom_beau
1
Да, пожалуйста, добавьте ссылку - это позволит читателям добавлять свои замечания в отчет.
Оффер
Не вижу как. Если вы переходите по ссылке, вам нужна учетная запись Intel, чтобы увидеть ее ??? Может я не прав ??? Скажи мне ... Я открыл билет, и он в моем аккаунте.
dom_beau
Может быть, вы можете перейти к обсуждению, которое я веду на форуме: форум по компилятору C ++
dom_beau
1

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

int i = 1; cout << i << " " << ++i << endl;

Если 2 2вместо вывода выводится 1 2, то компилятор не соответствует и, возможно, все еще рассматривает такой случай как UB. В этом случае значения Sentinel могут быть ошибочно использованы при вызове reset(). То же самое происходит с удалением объекта, созданного путем помещения нового в предварительно выделенный статический буфер, в режиме отладки он перезаписывается некоторыми реализациями со значениями часового типа.

Свифт - пятничный пирог
источник
Это дает 1 2в обоих 64-битной и 32-битной , Debug и Release .
dom_beau
2
Ошибка в _Ref_count_basecTor по умолчанию, который указан = default. Два члена _Uses = 1и _Weaks = 1установлены 1и 0соответственно. Кажется, что сгенерированный по умолчанию cTor прослушивается. Смотреть memoryфайл ...
dom_beau
@dom_beau хорошо, стоит отчета, также мы знаем, что Инициализация в C ++ - Серьезно Bonkers
Swift - Пятничный пирог