[c++] weak_ptr 재설정이 shared_ptr에 영향을 줍니까?

나는 사용에 익숙하지 않으며 매우 weak_ptr혼란스러운 상황에 직면하고 있습니다. 내가 사용하고 인텔 XE 2019 작곡가 업데이트 5 ( 패키지 2019.5.281을 함께 combinaison에) 버전의 Visual Studio 2019. 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

버그는 디버그 에서만 발생합니다 . Release 에서 빌드 하면 예상 결과가 나타납니다.



답변

인텔 ICC 측의 실제 버그 인 것 같습니다. 나는 그것을보고했다.

이 문제를 정확히 찾아 낼 수 있도록 다시 한 번 감사드립니다.


답변

센티넬 값을 가진 디버그 라이브러리의 버그처럼 보입니다. 언급 한 줄을 사용하여 쉽게 확인할 수 있습니다.

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

출력이 2 2대신에 1 2, 컴파일러는 호환되지 않으며, 여전히 그러한 경우를 UB로 간주합니다. 이 경우에는 Sentinel 값이 호출에 잘못 사용될 수 있습니다 reset(). 사전 할당 된 정적 버퍼 내에 새로운 배치로 생성 된 객체를 삭제하는 경우에도 비슷한 현상이 발생합니다. 디버그 모드에서는 센티넬 값이있는 일부 구현으로 덮어 씁니다.


답변