Nie jestem przyzwyczajony do używania weak_ptr
i 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_ptr
modyfikacja / unieważnienie następuje po weak_ptr
zresetowaniu 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.
źródło
-572662307 = 0xDDDDDDDD
co jest sposobem msvc na wskazanie wolnej pamięci stertyOdpowiedzi:
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.
źródło
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:
Jeśli dane wyjściowe są
2 2
zamiast1 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łaniemreset()
. 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.źródło
1 2
zarówno w wersji 64-bitowej, jak i 32-bitowej , debugowania i wydania ._Ref_count_base
domyślnym cTor, który jest określony= default
. Dwaj członkowie_Uses = 1
i_Weaks = 1
są odpowiednio ustawione1
i0
. Wygląda na to, że domyślnie wygenerowany cTor jest uszkodzony. Zobaczmemory
plik ...