2014-07-11 6 views
0

std :: unique_ptr에 문제가 있습니다. 나는 그들을 이해했다고 생각했지만 명확하게 이해하지 못했습니다.std :: unique_ptr과 관련된 오류

나는 다음과 같은 코드가 있습니다 :

X::X() : m_foo(nullptr), 
{ 
    m_foo = std::unique_ptr<Foo>(new Foo()); 
} 

X::X(Foo* foo) : m_foo(nullptr), 
{ 
    m_foo = std::unique_ptr<Foo>(foo); 
} 

std::unique_ptr<Foo> m_foo; 

다음과 같이 나는 X를 구성 할 때 : 포인터가 해제되고 있었다 :

Foo foo; 
X x(&foo); 

내가 객체 0x101f7eec0에 대한 오류 '고 말해 런타임 오류가 발생합니다 할당되지 않음 '. 다음

단, I는 X를 구성 :

Foo foo; 
X x; 

이러한 오류가 발생하지 않는다. 나는 다음과 같은 소멸자를 추가하는 경우

는 :

X::~X() 
{ 
    m_foo.release(); 
} 

모든 확인을 작동합니다.

왜 처음에는 오류가 발생하는지, 왜 foo를 해제하면 오류가 없어지는지 잘 모르겠습니다.

누군가 설명해주십시오.

+0

, 당신은 nullptr''에'm_foo'를 초기화 한 후 새로 지어진'표준을 할당 할 필요가 없습니다 :: unique_ptr '. 적절한 포인터로'm_foo (new Foo())'와'm_foo (foo)'를 사용하여'm_foo'를 즉시 초기화 할 수 있습니다. 명시 적 멤버 이니셜 라이저의 전체적인 점은 멤버 구성 후 할당 된 반 패턴을 피하는 것입니다. – user4815162342

답변

3

std::unique_ptr 동적으로 할당 된 개체 (즉, new 등을 사용하여 만든 개체)의 수명을 관리하기위한 것입니다.

실패한 예에서는 foo이 자동 저장 장치로 생성되므로 수명을 관리 할 필요가 없습니다 (그렇게하면 어쨌든 관찰 된 오류가 발생합니다). 컴파일러는 범위를 벗어나면 자동으로 파기합니다.

+0

원시 포인터에서 unique_ptr을 만들 수 없다는 말입니까? – ksl

+0

@ksl 할 수는 있지만 그렇게하면 포인터의 소유권을 unique_ptr로 옮길 수 있습니다. 결과적으로, unique_ptr은 unique_ptr을 파기하면 포인터에서'delete'를 호출하려고합니다 (또는 지정된 경우 사용자 정의 삭제자를 호출합니다). – ComicSansMS

+0

그리고 스택에 생성 된 객체에 대해 delete를 호출 할 수 없습니다. 따라서 소멸자에서 foo를 해제하면 컴파일러에서 삭제를 호출하지 말라고 알립니다. 그게 맞습니까? 나는 또한 호출자가 범위를 벗어나면 X가 파괴되고 foo가 파괴 될 때 unique_ptr이 파괴 될 것이기 때문에 메모리 누수가 발생하지 않을 것이라고 생각 하는가? – ksl

3

당신이 수행 할 때이

Foo foo; 
X x(&foo); 

foo는 스택에 할당됩니다. 스택에있는 객체는 unique_ptr에 포함될 수 없습니다. 객체가 힙에있는 경우에만이 작업을 수행 할 수 있습니다

이 ComicSansMS의 대답에 추가
Foo* foo = new Foo(); 
X x(foo);