본문 바로가기

c++ 언어/Effective C++

항목 13 : 자원 관리에는 객체가 그만! (1)

여기서 부터는 내용이 어려워 진다.

준비할게 있는데  boost 라이브러리

전 우분투가 있어서  sudo apt-get install libboost-dev libboost-doc   요것만 하면  알아서  install   우분투 짱임

shared_ptr 에 대해 알아야 한다.  auto_ptr 도 있는데  shared_ptr 에 익숙해 져야 한다.

이게  boost 라이브러리에 서 사용하는 클래스이다.

 일단  shared_ptr 에 대해 익숙해 져야 한다.

자세한 사용법은  네이버에서 검색해서 스터디 하시고

shared_ptr 사용시 주의 해야 될 점...

class A

{

public:

    A() {

        std::cout<<"construct test"<<std::endl;

    }

    ~A() {

        std::cout<<"destroy test"<<std::endl;

    }

    boost::shared_ptr<A> test()

    {

        boost::shared_ptr<A> pFromThis(this);

        std::cout<<pFromThis.use_count()<<std::endl;

        return pFromThis;

    }

};

int main()

{

    boost::shared_ptr<A> p(new A);

    boost::shared_ptr<A> p2 = p->test();

    std::cout<<p.use_count()<<std::endl;

    return 0;

}


결과

construct test

1

1

destroy test

destroy test

*** glibc detected *** ./shared_ptr2: double free or corruption (fasttop): 0x08cf9008 ***


위의 코드에서 주석을 풀면  실행시  런타임 에러가 난다.
shared_ptr 은  참조카운터 방식으로  계산하여 0이 되면 delete 를 하는데
 test() 함수가  문제가 있다.

boost::shared_ptr<A> p(new A); 
p 객체는 참조 카운터가 1이다
여까지는 정상 코드
그 다음 test 함수에서 하는 일을 보자
boost::shared_ptr<A> pFromThis(this)
해석해 보면   shared_ptr<A> 타입의 변수 pFromThis  를 만들었는데  this 의 주소를 저장하고 있다.
new 로  class A 생성자를 호출하는게 아니다. 그냥  포인터처럼 주소를 저장하고 있다.
이걸  그대로 리턴한다.
그러면 p2 는  p  의 주소값을 저장하고 있겠지?
그런데 문제는 p2가  p를 정상적으로 copy를 한게 아니다.
p2 = p;  요게 정상적으로 copy를 한 것인데
위의 코드처럼   편법(?)으로  하면  count 가 증가 되지 않는다.

그래서 중괄호 문을 빠져 나오면  count는 1인데  p, p2 를  소멸자를 호출하니
코드가 뻗어 버린것이다.

추가)
포인터 처럼 생각하면  별문제 없는 코드다  
int *p;
p = &a;
요것처럼
근데  c++ 의 클래스 템플릿인  shared_ptr 을 쓰고 있다.
단순히 shared_ptr 이 쓰기에는  포인터처럼 쓰지만
규칙이 있으므로   operator = 함수를 거치지 않고 사용자 임의의 주소를 할당해 버리면 이처럼 문제가 생기는 거다.  (자기주소 대입) ...