C++0x의 shared_ptr

C++은 garbage collection을 지원을 하지 않기 때문에 생성한 heap 객체를 언제 free해 줘야 할 지가 중요한 issue가 된다.(그런데 정말로 C++가 garbage collection을 지원하지 않나..?) 이는 ‘잘 쓰면’ 문제가 없지면 문제는 어떤 객체의 수명이 언제까지인지, 그리고 누가 들고 있는지를 고려하면서 프로그래밍을 하는 것은 때때론 지나치게 어렵다는 것이다..

JAVA에서 어떤 객체가 garbage collect될 조건은 바로 그 객체를 가리키는 reference가 하나도 없을떄이다. 그리고 gc는 주기적으로 이것을 체크한다. C++0x에도 이와 똑같은 방식으로 heap memory를 계속 해재해 줄 수 있도록 std::shared_ptr<T>를 지원한다.(원래는 boost library에 있었다 한다)

1. 사용법

#include<memory>
#include<iostream>
using namespace std;

class A{
public:
	int x;
};

int main(){
	shared_ptr<int> p1(new int(4));
	shared_ptr<int> p2(p1); // reference count를 1 늘린다.
	shared_ptr<int> p3(new int(4));
	shared_ptr<A> p2(new A());

	(*p2).x = 123;
	cout << "p1 == p2 : " << (p1 == p2) << endl; // result : 1
	cout << "p1 == p3 : " << (p1 == p3) << endl; // result : 0 ; == is pointer-equivalence
	cout << "*p1 == *p3 : " << (*p1 == *p3) << endl; // result : 1
	cout << "p2->x : " << p2->x << endl;
	return 0;
}

원래 pointer T*가  있을 자리에 shared_ptr<T>를 다 넣기만 하면 된다 ㅇㅇ

STL container도 다 쓸 수 있는데(set, map, vector..) 이유는 comparator가 잘 정의가 되어 있기 때문이다. == 연산자는 ‘주소가 같은가?’를 비교하고 <, > 연산자는 주소값을 비교한다.(shared_ptr<T>간의 비교는 T의 comparator<를 부르지 않는다!!) (http://en.cppreference.com/w/cpp/memory/shared_ptr/operator_cmp)

위 코드에서 memory leak은 없다. 이유는 shared_ptr이 reference count를 체크하면서 자기가 빠졌을 때 count가 0인 애들에 대해 저절로 free를 다 해주기 때문이다.

2. 주의할 점

다음과 같은 코드는 망한다

#include<memory>
#include<iostream>
using namespace std;

int main(){
	int p = new int(4);
	{
		shared_ptr<int> p1(p);
		cout << *p1 << endl;
	}
	*p = 123;
	cout << *p << endl;
	return 0;
}

아래도 망한다. 이 때는 weak_ptr을 써야 한다고 하는데 어떻게 하는지는 찾아봐야 할 듯 하다

#include<memory>
using namespace std;

class Faulty{
public:
	shared_ptr<Faulty> toSharedPtr()
	{ return shared_ptr<Faulty>(this); }
};

3. 그 외

Thread-safe하다고 한다. 어떤 개체에 대해 여러 개의 shared_ptr<T>를 실시간으로 여러 개 생성하고 파괴해도 안전하다. 단, 인자를 &로 전달했을 경우엔 nonsafe할 수 있다고 한다.

shared_ptr<T> 간의 복사는 약간의 copy load가 있다고 한다.

shared_ptr<T>간의 static_cast, dynamic_cast, const_cast는 static_pointer_cast(), dynamic_pointer_cast(), const_pointer_cast() 함수를 불러서 해결할 수 있다.(http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s