2012-09-12 4 views
3

최근에 반환 된 빈 shared_ptr을 사용할 때 이상한 동작을 감지했습니다. 호출 다음dereferencing이 반환 될 때 불일치가 발생했습니다. empty shared_ptr

struct A { 
     A() { } 
     void foo() { 
     std::cout << "A::foo" << std::endl; 
     } 
    }; 

    struct B { 
     B() :i(42) { } 
     void foo() { 
     std::cout << "B:foo with i: " << i << std::endl; 
     } 

     int i; 
    }; 

    template<typename T> 
    std::shared_ptr<T> create_empty() { 
     return std::shared_ptr<T>(); 
    } 

: : 문제는이 예제를 고려 설명하기 위해

std::shared_ptr<A> pa(create_empty<A>()); 
    pa->foo(); // #1: Works fine and prints: "A::foo". 

    std::shared_ptr<B> pb(create_empty<B>()); 
    pb->foo(); // #2: Throws an exception. 

이제 내 질문은 왜 # 1 작품을 호출한다 (나뿐만 아니라 예외를 얻을 것으로 예상)이 올바른 경우 # 1의 작동을 막는 방법. 반환 값이 비어 있는지 확인해야합니까? 거기에 null 또는 빈 shared_ptr를 반환하는 다른 방법이 있습니까? 그게 중요하다면 MSVC++ 11을 사용하고 있습니다 ...

+0

일반적으로 C++은 사용자가 명시 적으로 요청하지 않으면 값 비싼 검사를 추가하지 않습니다. 자신의 재량에 따라 코드에'if (pa)'를 추가하는 것은 전적으로 자유 롭습니다. –

답변

3

두 경우 모두의 코드는 널 포인터를 역 참조합니다. 동작은 정의되지 않았으므로 의미가있는 것 등 모든 일이 발생할 수 있습니다. 그것들을 이해하려고 노력하지 마라. 정의되지 않음은 정의되지 않습니다.

+0

좋습니다. 이해해 둡니다. 조금 혼란 스러울 것 같아요. 따라서 반환 값을 역 참조하기 전에 검사를 수행해야합니다. 귀하의 답변에 많은 감사드립니다. – mkh

+0

@mkh - 점검 할 사항이 없습니다 (공식적으로 검사 할 이유는 없지만 컴파일러는이를 확인하지 않습니다). 이것이 정의되지 않은 행동의 핵심입니다. 아무 것도 확인하지 않아도됩니다. –

+0

@mkh - 오, 미안, 방금 네가 한 말을 깨달았다. 네, 물건에 접근하고 싶으면 확인해야합니다. –

1

null 포인터를 사용하기 때문에 예제가 실제로 작동하지 않습니다.

첫 번째 경우에는 A에서 아무 것도 액세스하지 않으므로주의하지 못할 수 있습니다. 두 번째 경우에는 i 멤버에 액세스 할 때 매우 this 포인터를 참조 해제해야하며 시스템에서 null임을 알게됩니다.