영넌 개발로그

[C ++ 기초] 예외 처리 exception handling (try - catch) 본문

코딩/C++

[C ++ 기초] 예외 처리 exception handling (try - catch)

영넌 2020. 12. 6. 19:48

exception handling

c언어에서 error가 나면 stop으로 프로그램 종료가 되었다. 이건 별로 좋지 않은 현상이다. 에러시 다른 조치를 취할 수 있도록 해주기 위해 예외를 처리해주어야 한다. 그거를 하는 방법엔 try catch 라는 방법이 있다.

 

예를 들어, 할당된 영역을 벗어나서 메모리를 사용하려하면 런타임 에러가 뜬다. (Expression: vector subscript out of range) 디버깅 모드에서는 런타임 동안에 체크를 해서 보여준다.

 

코드를 상용화할 때에는 릴리즈 모드로 해야하는데 릴리즈 모드에서는 속도가 중요하기 때문에 메모리를 벗어난다던가 하는 것에 대해서는 체킹하는게 빠진다. 따라서 릴리즈 모드에서는 아래와 같은 에러가 나지 않고 콘솔에서 잘 실행 되는 것을 볼 수 있다. index에 큰 숫자를 넣으면 비정상종료가 되었다고 음수인 code만 띄워줄 뿐, 어느 부분에서 어떻게 오류가 나는지 알려주지 않는다.

 

이와 같은 경우에서 비정상 종료되지 않도록 해주는 것이 exception handling 기능이다.

 

Debug mode
Release mode

실행 코드 >

#include <iostream>
#include <vector>

int main() {
	std::vector<int> v{ 1,2,3,4 };

	std::cout << v[5] << '\n';

	std::cout << "Ended with success"<< '\n';

	return 0;
}

 

 

 

 

헤더는 #include <exception> 이 필요하다

try { } 안에는 실행하고자 하는 코드를 작성한다. 이 안에 코드를 실행하다가 오류가 난다면 catch { } 로 넘어간다. 

exception& e는 모든 에러를 잡는다. e.what( )을 통해 뭐가 잘못된 것이지 출력할 수 있다.

인덱싱 에러를 잡고 싶다면 v.[5]와 같이 쓰는 것이 아니라 벡터의 at( )메소드를 통해 에러를 잡을 수 있다. 

	try {
		std::cout << v.at(_idx) << '\n';
	}
	catch (std::exception& e) {
		std::cout << e.what() << '\n';
	}

 

오류의 종류에 따라서 각각 다른 처리를 하고 싶다면?

 

catch를 여러번 써주면 된다. exception으로부터 상속을 받아서 out_of_range, length_error 등을 쓸 수 있다. 이를 통해 세부적인 에러를 잡을 수 있다. 제일 먼저 잡힌 오류만 프린트되고 끝난다. 먼저 나온 catch에서 맨 처음에 하나만 잡히므로 순서에 상관 있다. 

부모 클래스인 exception은 모든 오류를 잡을 수 있는 클래스이다.

	try {
		std::cout << v[5] << '\n';
		v.resize(v.max_size() + 1);
	}
	catch (std::out_of_range& e) {
		std::cout << "인덱스 오류" << '\n';
	}
	catch (std::length_error& e) {
		std::cout << "사이즈 조절 오류" << '\n';
	}
    	catch (std::exception e) {
		std::cout << "EXCEPTION";
	}

 

 

Comments