티스토리 뷰
자원 관리에는 객체가 그만!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//여러 형태의 투자를 모델링한 클래스 계통의 최상위 클래스
class Investment { . . . };
/*Investment 클래스 계통에 속한 클래스의 객체를
동적 할당하고 그 포인터를 반환합니다.
이 객체의 해제는 호출자 쪽에서 직접 해야 합니다.*/
Investment* createInvestment();
void f()
{
//팩토리 함수를 호출합니다.
Investment *pInv = createInvestment();
// pInv를 사용합니다.
// TODO
// 객체를 해제합니다.
delete pInv;
}
|
cs |
1. ( . . . )부분 어딘가에서 return문(도중하차)이 있을 가능성이 있습니다.
2. Continue 혹은 goto 문에 의해 갑작스레 루프로부터 빠져나올 가능성이 있습니다.
3. ( . . . )부분의 어떤 문장에서 예외를 던질 가능성이 있습니다.
4. 객체를 담고 있는 메모리가 누출되고, 그와 동시에 그 객체가 갖고 있던 자원까지 모두 샙니다.
해결방법1
자원을 객체에 넣고 그 자원 해제를 소멸자가 맡도록 하며,
실행 제어가 f를 떠날 때 C++가 자동으로 호출해 주는 소멸자에 의해 해당 자원을 저절로 해제 할 수 있습니다.
ex 1> auto_ptr : 포인터와 비슷하게 동작하는 객체[스마트 포인터(smart pointer)]로서, 가리키고 있는 대상에 대해 소멸자가 자동으로 delete를 불러주도록 설계
1
2
3
4
5
6
7
|
void f()
{
//팩토리 함수를 호출합니다.
std::auto_ptr<Investment> pInv ( createInvestment( ) );
// 예전처럼 pInv를 사용합니다.
// auto_ptr의 소멸자를 통해 자동으로 소멸
}
|
cs |
//pInv를 삭제합니다.
※자원 관리에 객체를 사용하는 방법의 특징!!
1. 자원을 획득한 후에 자원 관리 객체에게 넘깁니다. ( 자원 획득 즉 초기화( RAII ) )
2. 자원 관리 객체는 자신의 소멸자를 사용해서 자원이 확실히 해제되도록 합니다.
auto_ptr은 자신이 소멸될 때 자신이 가리키고 있는 대상에 대해 자동으로 delete를 먹기 때문에, 어떤 객체를 가리키는 auto_ptr의 개수가 둘 이상이면 안된다. 개체를 복사하면 원본 객체는 null로 만든다. 복사하는 객체만이 그 자원의 유일한 소유권을 갖는다.
std::auto_ptr pInv1( createInvestment ( ) );
//pInv1 = createInvestment함수에서 반환된 객체
std::auto_ptrpInv2( pInv1 ); //pInv2 = 객체, pInv1 = null
pInv1 = pInv2; //pInv1 = 객체, pInv2 = null
해결방법2
shared_ptr :
참조 카운팅 방식 스마트 포인터( RCSP ), 특정한 어떤 자원을 가리키는(참조하는) 외부 객체의 개수를 유지하고 있다가 그 개수가 0이 되면 해당 자원을 자동으로 삭제하는 스마트 포인터
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
void f()
{
// pInv1 = 객체
std::tr1::shared_ptr<Investment> pInv1( createInvestment( ) );
// pInv1 = pInv2 = 객체
std::tr1::shared_ptr<Investment>pInv2( pInv1 );
//pInv1 = pInv2 = 객체
pInv1 = pInv2;
// pInv1 및 pInv2는 소멸되며, 이들을 가리키고 있는 객체도 자동 삭제 됩니다.
}
|
cs |
잘못된 사용
1
2
3
4
5
6
|
std::auto_ptr<std::string>aps(new std::string[10]);
std::tr1::shared_ptr<int> spi( new int[1024] );
|
cs |
std::auto_ptr 및 tr1::shared_ptr은 소멸자 내부에서 delete [ ]가 ‘아닌’ delete 연산자를 사용하기 때문입니다. 컴파일에러가 발생하지 않습니다.
C++표준 라이브러리에서는 동적 할당된 배열을 위해 준비된 std::auto_ptr 혹은 std::tr1::shared_ptr 같은 클래스가 제공되지 않습니다.
이는 string 및 vector로 거의 대체할 수 있기 때문입니다.
자원을 관리하는 객체를 써서 자원을 관리하는 것이 중요!!!!!!!
결론
자원 누출을 막기 위해, 생성자 안에서 자원을 획득하고 소멸자에서 그것을 해제하는 RAII객체를 사용합시다.
일반적으로 널리 쓰이는 RAII 클래스는 std::auto_ptr 그리고 std::tr1::shared_ptr 입니다.
이 둘 가운데 std::tr1::shared_ptr이 복사 시의 동작이 직관적이기 때문에 상용함이 편리 합니다.
반면, auto_ptr은 복사되는 객체(원본 객체)를 NULL로 만들어 버립니다.
- Total
- Today
- Yesterday
- Linux
- C# 고급 기술
- 암호화
- script
- 스쿠버 다이빙
- 스쿠버다이빙
- C++
- CMake
- C#
- OpenSource
- 제주도
- 서귀포블루버블
- 블루버블다이브팀
- 성산블루버블
- Build
- Windows
- DLL
- PowerShell
- C
- C#.NET
- 울릉도
- 외돌개
- 블루버블
- 블루버블다이빙팀
- 티스토리챌린지
- 서귀포
- 현포다이브
- 네트워크 정보
- 패턴
- 오블완
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |