[C/C++] 예외 처리(except handling)
예외(exception)란 컴퓨터 시스템이 동작하는 중에 예상하지 못한 오류가 발생하여 실행되고 있던 프로그램이 중지되는 것을 의미한다.
예를 들어,
std::vector<int> v(3);
std::cout << v.at(4);
크기가 3이나 4번째 원소를 요청하고 있는 경우 실행 시 오류가 발생되어 프로그램이 중지된다. 혹은 큰 메모리를 할당하는 경우도 예외를 발생시킨다.
C에서는 메모리 동적 할당 시 사용하는 malloc의 특성을 이용해 예외처리를 할 수도 있었는데, 다음과 같다.
char *c = (char *)malloc(100000000000);
if (c == NULL)
{
printf("메모리 할당 오류");
return;
}
malloc은 메모리 할당을 실패할 때 NULL을 리턴하기 때문에 c가 NULL인지를 확인하여 예외 상항을 처리할 수 있다. 그러나 상당히 귀찮고 불편한 상황이 발생하기 때문에.. C++에서는 다음과 같은 예외 처리 문법을 제공한다.
- try : 예외가 발생할 가능성이 있는 코드 블럭
- throw : try문에서 발생한 오류에 대한 정보를 담은 코드 블럭
- catch : 발생한 예외에 대해 예외 핸들러가 처리할 내용을 담은 코드 블럭
*주의
try문을 사용할 때는 반드시 한 개 이상의 catch를 구현해야 한다. catch는 자신이 처리할 수 있는 예외 타입을 지정할 수 있는데, 줄임표인 … 를 사용하면 해당 catch 절은 모든 타입의 예외를 처리하게 된다. 이렇게 줄임표를 사용한 경우, catch절의 위치는 언제나 catch절 중 맨 마지막에 위치해야 한다.
try와 catch는 같이 쓰이므로 throw부터 살펴보자면..
throw로는 예외로 전달하고 싶은 객체를 써주면 된다.
예를 들어 이런 느낌으로..
const T& at(size_t index) const
{
if (index >= size)
{
throw std::out_of_range("vector의 index가 범위를 초과했습니다.");
}
return data[index];
}
(생략)
이렇게 예외를 throw로 처리하게 되면 throw한 위치에서 즉시 함수가 종료되고 예외 처리하는 부분까지 점프하게 된다. 따라서 throw 밑에 있는 모든 문장은 실행되지 않는다. 중요한 부분은 함수에서 예외 처리하는 부분에 도달하기까지 함수를 빠져나가면서 stack에 생성되었떤 객체들을 빠짐없이 소멸시켜준다는 것이다. 따라서 소멸자를 잘 작성해두면 예외가 발생해도 사용하고 있는 자원들을 제대로 소멸시킬 수 있다.
<try&catch>
try를 사용할 때는 한 개 이상의 catch를 구현한다. 이렇게..
try
{
data = vec.at(index);
}
catch (std::out_of_range& e)
{
std::cout << "예외 발생" << e.what() <<std::endl;
}
try문 안에서는 무언가 예외가 발생할만한 코드가 실행된다. 예외가 발생하지 않았다면 try&catch문이 없는 것과 동일하게 실행된다. try문 안에 data에는 vec의 index번째 값이 들어가고 밑에 있는 catch문은 무시된다.
예외가 발생하게 되면 즉시 stack에 생성된 모든 객체들의 소멸자들이 호출되고 가장 가까운 catch문으로 점프한다.
Leave a comment