예외 처리

강한친구·2022년 3월 7일

C / CPP

목록 보기
15/19

c언어에서의 예외

c에서는 사실 별도의 예외처리가 존재하지 않았따. 그냥 결과값이 이러면 어떻게 해달라는 if문을 작성했다.

char *c = (char *)malloc(1000000000);
if (c == NULL) {
  printf("Memory Error");
  return;
}

다만 이러한방식은 코드가 복잡해지면 복잡해질수록 작성하기 어려워지고 코드 또한 지저분해진다.

throw

cpp에서는 예외가 발생하면 throw문을 사용해서 예외발생을 명시적으로 나타낼 수 있다.

const T& at(size_t index) const {
  if (index >= size) {
    throw std::out_of_range("Vector range error");
  }
  return data[index];
}

이처럼 예외상황에서 throw를 통해 상황에 맞는 객체를 예외로 전달하고 예외처리코드 까지의 모든 코드를 생략한다.

try-catch

예외처리가 발생할만한 코드는 이 try catch문으로 감싸면 된다.

try안에 있는 코드가 작동하고, 만약 오류가 난다면 미리 작성한 throw문의 코드가 작성하고 catch 문까지 건너뛰게 된다. 이 떄 미리 throw에서 던진 out_of_range를 보게되고, catch문은 이를 받아 what()으로 볼 수 있다.

스택 풀기

예외처리를 해주면 가장 가까운 catch에서 예외를 받는다. 이 과정에서 예외가 전파되면 스택 메모리가 해제된다. 따라서 이를 고려해서 코드를 잘 작성해아한다.

여러개의 예외 받기

예외를 여러개 받으려면, catch문을 여려번작성해서 에러별 상황을 만들어주면 된다.

int main() {
  int c;
  std::cin >> c;

  try {
    func(c);
  } catch (char x) {
    std::cout << "Char : " << x << std::endl;
  } catch (int x) {
    std::cout << "Int : " << x << std::endl;
  } catch (std::string& s) {
    std::cout << "String : " << s << std::endl;
  } catch (const char* s) {
    std::cout << "String Literal : " << s << std::endl;
  }

모든 예외 받기

 try {
    func(c);
  } catch (int e) {
    std::cout << "Catch int : " << e << std::endl;
  } catch (...) {
    std::cout << "Default Catch!" << std::endl;
  }
}

이와 같이 catch(...)을 써주면 위에서 지정된 예외를 제외하고 모든 예외를 받아준다.

예외가 없는 nonexcept

int fucntion() nonexcept {}

이런식으로 선언을 해주면 뒤에 throw가 오더라도 예외처러없이 간다.

cpp11 부터는 소멸자들은 전부 nonexcept라고 한다. 따라서 절대로 소멸자에는 예외처리를 하면 안된다.

0개의 댓글