Скидання слабкого_птр впливає на спільний_птр?


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-бітовій . У цій більш пізній конфігурації результат - це те, що очікується.

EDIT 2

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



2
Я думаю, що у вашій реалізації є помилка. gcc дає правильні результати
NathanOliver

1
Неможливо відтворити у Visual Studio 2019 (v. 16.2.5)
Frodyne

1
Ні, це однозначно не нормально.
химерний

4
У випадку, якщо це допоможе налагоджувати, -572662307 = 0xDDDDDDDDщо є способом msvc вказувати звільнену пам’ять купи
Ерік

Відповіді:


2

Здається, це справжня помилка на стороні Intel ICC; Я повідомив про це.

Ще раз дякую, що допомогли мені вирішити цю проблему.


1
Чи можете ви додати у своїй відповіді посилання на звіт про помилку? Таким чином, будь-хто з тією ж проблемою може бути переданий у звіт про помилку щодо його статусу.
Сандер Де

Я скоріше додам коментар, як тільки справа буде виправлена.
dom_beau

1
Так, будь ласка, додайте посилання - це дозволить читачам додати свої зауваження до звіту.
півзахисник

Не розумію, як. Якщо ви перейдете до посилання, вам потрібен обліковий запис Intel, щоб побачити його ??? Може, я помиляюся ??? Скажіть ... Я відкрив квиток, і він є на моєму рахунку.
dom_beau

Можливо, ви можете дійти до дискусії, яку я веду на форумі: C ++ компілятор форум
dom_beau

1

Це схоже на помилку в бібліотеці налагодження із значеннями дозорних даних. Це легко перевірити, за допомогою вказаного рядка:

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

Якщо вивід є 2 2замість 1 2, компілятор не сумісний і, можливо, все ще вважає такий випадок UB. Значення Sentinel можуть використовуватися помилково в цьому випадку з викликом reset(). Подібне відбувається і з видаленням об'єкта, створеного шляхом розміщення нового в попередньо виділеному статичному буфері, в режимі налагодження він перезаписується деякими реалізаціями зі значеннями дозорних.


Він дає 1 2як 64-розрядні, так і 32-розрядні програми , налагодження та випуск .
dom_beau

2
Помилка знаходиться у _Ref_count_baseстандартному cTor, який вказано = default. Два члена _Uses = 1і _Weaks = 1встановлюється 1і 0відповідно. Здається, що cTor, створений за замовчуванням, помиляється. Дивіться memoryфайл ...
dom_beau

@dom_beau добре, варто доповісти, також ми знаємо, що Ініціалізація в C ++ є серйозно Бонкерс
Swift - П’ятниця Пиріг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.