리소스를 정리하기 전에 예외가 발생한 경우

동적할당등을 받은 메모리가 아직 해제가 안된 상태에서 예외처리에 의한 함수 종료는 심각한 메모리 누수 현상을 가져올 수 있다.

#include 

using namespace std;

void A();
void B();
void C();

int main()
{
    try
    {
        A();
    }
    catch(int ex)
    {
        cout << "예외 처리" << endl;
    }
}

void A()
{
    // 메모리를 할당
    char* p = new char [100];   // 메모리를 100바이트 할당

    // 여기까지 실행
    cout << "예외가 발생하기 전" << endl;
    B();

    // 이곳은 실행하지 않음을 출력
    cout << "예외가 발생한 후" << endl;
    delete[] p;
    p = NULL;
}

void B()
{
    throw "Exception!!";
}
  • 위 소스는 A() 함수의 앞에서 할당된 메모리가 해제되지 않는 문제가 발생.
  • 함수 끝에서 무언가 정리 작업을 해주는 경우가 있다면 모두 이 문제점에 노출

소멸자로 리소스 문제 해결하기

  • 함수 소멸시 함수안의 모든 변수 및 객체가 소멸
  • 객체는  소멸시 소멸자를 호출하는 방법을 이용
  • 이점을 이용, 리소스를 해제하는 용도의 클래스를 제작
  • 이것을 스마트 포인터라 부른다.
#include 

using namespace std;

class SmartPointer
{
public:
    SmartPointer(char* p)
        :ptr(p)
        {
            
        }
    ~SmartPointer()
        {
            // 소멸자가 호출되는 것을 확인한다.
            cout << "메모리가 해제된다." << endl;

            delete[] ptr;
        }
public:
    char* const ptr;
};

void A();
void B();

int main()
{
    try
    {
        A();
    }
    catch(const char* ex)
    {
        cout << "예외 처리" << endl;
    }

    return 0;
}

void A()
{
    // 메모리를 할당
    char* p = new char [100];   // 메모리를 100바이트 할당

    // 메모리를 스마트 포인터로 보관한다
    SmartPointer sp(p);

    // 예외를 던지는 함수 호출
    B();

    // 이곳은 실행하지 않음을 출력
    cout << "예외가 발생한 후" << endl;
    
   
    // delete[] p;
    // p = NULL;
}

void B()
{
    throw "Exception!!";
}
  • 함수가 정상적으로, 또는 예외에 의해서 종료된 경우 모두 스마트 포인터 객체 sp의 소멸자를 호출한다.
  • 소멸자단에서 메모리 해제등을 시켜주기 때문에 따로 신경쓰지 않아도 되게 된다.

주의 해야 할 점은 다음과 같다.

  • 생성자가 올바르게 종료된 경우만 객체를 생성한 것으로 간주한다.
  • 생성자에서 예외가 발생한 경우라면 정상적으로 종료된게 않은 것이고  객체도 생성되지 않은 것이다.
  • 객체가 생성되지 않았으니 소멸자도 호출될 일이 없다.
  • 결국 생성자단에서 일어난 메모리 누수를 해결하기 위한 예외를 다시 던져야 한다.

소멸자에서의 예외는 반드시 막아야 한다.

  • 객체의 소멸자에서 예외가 던져지는 경우 프로그램이 비정상 종료할 수 있다.
  • 소멸자 밖으로는 예외가 던져지지 않게 막아야 한다.
  • 생성자에서 했던 것처럼 소멸자의 모든 코드를 try블록으로 감쌀 필요가 있다.
  • 잡아낸 예외는 절대로 소멸자 밖으로 다시 던져서는 안 된다

저작자 표시
신고

'컴퓨터 언어 > C++' 카테고리의 다른 글

파일 입출력  (0) 2012.12.28
예외 처리, 예외에 안전한 코드 만들기  (0) 2012.12.24
예외 처리, 함수 깊숙히  (0) 2012.12.24
예외 처리  (0) 2012.12.21
오버라이딩  (0) 2012.12.20
가상함수를 이용한 다형성 구현  (0) 2012.12.20


티스토리 툴바