티스토리 뷰


이펙티브 STL 서적을 읽고 있던중 auto_ptr 컨테이너(COAP: Container Of A(a)uto_P(p)tr)는 절대 금지라고 강조하는 부분이있었습니다.

 

책의 저자는 COAP를 만드는 코드는 컴파일조차되어서는 안된다고 강조합니다. -_-!

 

그 결정적인 이유는 COAP는 이식이 불가능하다는 점입니다.

 

이 점을 풀어서 설명드리자면 auto_ptr 하나를 복사(copy)하면, auto_ptr이 가리키는 객체의 소유권(ownership)은

 

복사하는 (copying) auto_ptr로 옮겨지고 복사되는 (copied) auto_ptr는 NULL로 셋팅된다는 것입니다.

 

즉 auto_ptr을 복사하는 것은 '그 포인터의 값을 바꾸는 것이다.' 라고 말할 수 있겠습니다.

 

이렇게 이식이 불가능한 상황인데 STL은 "모든것이 복사된다"라는 가정 하에 구축된 라이브러리이니

 

STL로 컨테이너에 auto_ptr을 같이 사용하면 문제가 생기는것은 당연하다고 볼수 있습니다.

 

그래서 저는 책을 읽고 auto_ptr이 복사되면 정말로 NULL로 변경되나 실험해봤습니다.

 

다음은 실험 코드입니다.

 

#include <iostream>

#include <memory> 

 

 

class Widget{

private:

int i;

 

};

 

void func(std::auto_ptr<Widget> lparam, std::auto_ptr<Widget> rparam)

{

std::cout<<"-- Function IN -- "<<std::endl;

if(lparam.get() == NULL)

{

std::cout<<"lparam is NULL"<<std::endl;

}

if(rparam.get() == NULL)

{

std::cout<<"rparam is NULL"<<std::endl;

}

std::cout<<"-- Function OUT -- "<<std::endl;

}

 

 

void Test1(){

std::cout<<"------- Test1 Start ------- "<<std::endl;

std::auto_ptr<Widget> pw1(new Widget);

std::auto_ptr<Widget> pw2(new Widget);

std::cout<<"-- Before -- "<<std::endl;

if(pw1.get() == NULL)

{

std::cout<<"pw1 is NULL"<<std::endl;

}

if(pw2.get() == NULL)

{

std::cout<<"pw2 is NULL"<<std::endl;

}

func(pw1,pw2);

 

std::cout<<"-- After -- "<<std::endl;

if(pw1.get() == NULL)

{

std::cout<<"pw1 is NULL"<<std::endl;

}

if(pw2.get() == NULL)

{

std::cout<<"pw2 is NULL"<<std::endl;

}

}

void Test2(){

std::cout<<"------- Test2 Start ------- "<<std::endl;

std::auto_ptr<Widget> pw1(new Widget);

std::auto_ptr<Widget> pw2(pw1);

if(pw1.get() == NULL)

{

std::cout<<"pw1 is NULL"<<std::endl;

}

if(pw2.get() == NULL)

{

std::cout<<"pw2 is NULL"<<std::endl;

}

}

void main(){

Test1();

Test2();

}

 

다음은 실험 결과입니다.

 

 

정말로 복사가 이뤄지고 난후에는 NULL이 되버리는군요 -_-;;

 

저는 메모리관리 이슈 때문에 auto_ptr을 쓸까하다가 Boost라이브러리를 사용했는데

 

정말 잘 한짓인거 같습니다!

 

앞으로 꼭 기억해 뒀다가 나중에 이런일로 당황하지 않게 주의해야 겠습니다.

 

누군가에게는 작은도움이 되었기를 바라면서 오늘의 포스팅 끝~   

댓글