słaby reset zresetować wpływa na share_ptr?

11

Nie jestem przyzwyczajony do używania weak_ptri mam do czynienia z dość mylącą sytuacją. Używam aktualizacji Intel XE 2019 Composer 5 ( pakiet 2019.5.281 ) w połączeniu z Visual Studio 2019 ver. 16.2.5 . Kompiluję w wersji 64-bitowej. Używam standardowego C ++ 17 .

Oto kod mojego rozwiązania szczytowego:

#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;
}

Oczekiwany wynik to:

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

... ale oto co otrzymałem:

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

Co się dzieje? Czy to normalne, że shared_ptrmodyfikacja / unieważnienie następuje po weak_ptrzresetowaniu powiązanego / an ? Jestem trochę zdezorientowany wynikami, które uzyskałem. Prawdę mówiąc nie spodziewałem się tego wyniku ...

EDYCJA 1

Chociaż błąd występuje w konfiguracji 64-bitowej , nie występuje w wersji 32-bitowej . W tej późniejszej konfiguracji wynik jest zgodny z oczekiwaniami.

EDYCJA 2

Błąd występuje tylko podczas debugowania . Kiedy buduję w wersji , otrzymuję oczekiwany wynik.

dom_beau
źródło
2
Myślę, że twoja implementacja ma błąd. gcc generuje poprawne wyniki
NathanOliver
1
Nie można odtworzyć w programie Visual Studio 2019 (wer. 16.2.5)
Frodyne,
1
Nie, to zdecydowanie nie jest normalne.
dziwaczny
4
W przypadku, gdy pomaga w debugowaniu, -572662307 = 0xDDDDDDDDco jest sposobem msvc na wskazanie wolnej pamięci sterty
Eric

Odpowiedzi:

2

Wygląda na to, że to prawdziwy błąd po stronie Intel ICC; Zgłosiłem to.

Jeszcze raz dziękuję za pomoc w dokładnym wskazaniu tego problemu.

dom_beau
źródło
1
Czy możesz dodać link do raportu o błędzie w swojej odpowiedzi? W ten sposób każdy, kto ma ten sam problem, może zostać skierowany do raportu o błędzie o jego status.
Sander De Dycker,
Raczej dodam komentarz, gdy sprawa zostanie naprawiona.
dom_beau
1
Tak, proszę dodać link - pozwoli to czytelnikom na dodawanie własnych uwag do raportu.
halfer
Nie widzę jak. Jeśli dojdziesz do linku, potrzebujesz konta Intel, aby go zobaczyć ??? Może się mylę??? Powiedz mi ... Otworzyłem bilet i jest on na moim koncie.
dom_beau
Może uda ci się dotrzeć do dyskusji, którą prowadzę na forum: C ++ forum kompilatora
dom_beau
1

Wygląda jak błąd w bibliotece debugowania z wartościami wartowników. Łatwo to sprawdzić, używając linii, o której wspomniałem:

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

Jeśli dane wyjściowe są 2 2zamiast 1 2, to kompilator nie jest zgodny i prawdopodobnie nadal uważa taki przypadek za UB. Wartości Sentinel mogą być błędnie użyte w tym przypadku z wywołaniem reset(). Podobnie dzieje się z usuwaniem obiektu utworzonego przez umieszczenie nowego w wstępnie przydzielonym buforze statycznym, w trybie debugowania zostaje on nadpisany przez niektóre implementacje wartościami wartownika.

Swift - piątek ciasto
źródło
Daje 1 2zarówno w wersji 64-bitowej, jak i 32-bitowej , debugowania i wydania .
dom_beau
2
Błąd jest _Ref_count_basedomyślnym cTor, który jest określony = default. Dwaj członkowie _Uses = 1i _Weaks = 1są odpowiednio ustawione 1i 0. Wygląda na to, że domyślnie wygenerowany cTor jest uszkodzony. Zobacz memoryplik ...
dom_beau
@dom_beau cóż, warto zgłosić, wiemy również, że inicjalizacja w C ++ to Poważnie Bonkers
Szybki - Piątek Pie