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.



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.


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.