#include <iostream>
using namespace std;
#include <memory> // auto_ptr, shared_ptr
class CTest {
public:
CTest() { cout << "CTest()" << endl; };
~CTest() { cout << "~CTest()" << endl; };
};
void New( void )
{
cout << "New() ----------------" << endl;
CTest* p = new CTest;
// delete p;
}
void AutoPtr( void )
{
cout << "AutoPtr() ----------------" << endl;
std::auto_ptr<CTest> p(new CTest);
}
void SharedPtr( void )
{
cout << "SharedPtr() ----------------" << endl;
std::tr1::shared_ptr<CTest> p (new CTest);
}
int main()
{
New();
AutoPtr();
SharedPtr();
}
1. new
당연히 delete를 해야하지만 인간이지라 함수 중간에 return을 만날수도 있고 try-catch에 걸리수도 있고 해서 delete를 못하면 메모리누수가 발생한다. New()함수
2. auto_ptr
그래서 나온게 auto_ptr이다. 소멸자에 객체해제가 있었서 사용자가 delete를 신경 안써도 된다. AutoPtr() 함수
하지만 문제점 발생: auto_ptr은 소유권개념이 있다.
std::auto_ptr<int> p1(new int(10)); // p1=10
std::auto_ptr<int> p2(p1); // p2=10, p1=null
//cout << *p1 << endl; // 에러발생
cout << *p2 << endl; // 10출력
p2가 p1을 복사하는 순간 new int(10)의 소유권이 p2에게 넘어가서
p2가 p1을 복사하는 순간 new int(10)의 소유권이 p2에게 넘어가서
p1은 null이고 p2가 new int(10)을 가리킨다.
이로 인해서 STL컨테이너에서는 사용하면 안된다.
(C++11부터 사용 중지권고했고 C++17부터는 제거 돼었다고 합니다.)
3. shared_ptr
그래서 나온게 shared_ptr이다. 참조 카운팅이 추가되었다.
std::tr1::shared_ptr<int> p1(new int(10)); // 참조 카운팅=1
std::tr1::shared_ptr<int> p2(p1); // 참조 카운팅=2
cout << *p1 << endl; // 10출력
cout << *p2 << endl; // 10출력
std::tr1::shared_ptr<CTest> p1(new CTest); // 생성자 호출
p2가 p1를 복사하는 순간 참조 카운팅은 2가 된다.
이 참조 카운팅이 0이 되는 순간에 delete를 한다.
하지만 문제점 발생
배열을 delete[]하지 않는다.
std::tr1::shared_ptr<CTest> p (new CTest[10]); // 생성자 10번 호출하지만 소멸자는 1번만 호출
이처럼 배열을 할당하면 소멸시 문제가 발생한다.
여러해결책이 있는데
배열대신 Vector를 사용하라고 한다.
std::vector<std::tr1::shared_ptr<CTest>> p(10); // 벡터 생성
std::vector<std::tr1::shared_ptr<CTest>> p(10); // 벡터 생성
std::tr1::shared_ptr<CTest> p1(new CTest); // 생성자 호출
std::tr1::shared_ptr<CTest> p2(new CTest); // 생성자 호출
// 2번 생성했으므로 소멸자 2번 호출함
댓글 없음:
댓글 쓰기