c++에서 exception을 처리함에 있어서 stack unwinding에 대해서 잘 알아야 한다
만약 c++에서 exception이 처리된다면
exception이 raise 되는 순간 함수가 stack에서 사라지며
catch 구문으로 옮겨지게 된다.
따라서 만약에 exception이 발생하는 코드 밑에 메모리 할당을 deallocation 하는 부분이 처리되지 않아서
메모리 leak이 발생할 수 있다.
따라서 스마트 포인터를 잘 사용해야 한다.
자세한 내용은 코드에 담아 두었다.
코드 >>
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include <iostream>
// stack unwinding에 대해서 잘 알아야 한다
// divide(10, 0)을 실행하면 throw가 실행되면서
// divide가 스택에서 없어지고 main 함수 뒤에는 바로
// catch exception이 바로 실행되게 된다.
// 만약 임의의 함수 f가 있을때
// f 안에 divide(10, 0)이 있다고 하자
// 그렇다면, divide(10,0)이 스택에서 없어지고
// f도 stack에서 없어지고
// 최종적으로 main 다음에 catch exception이 위치하게 된다
// 만약 catch exception이 없다면 main 함수에서 바로
// std::terminate이 실행되면서 프로세스가 종료되게 된다
// exception이 던져질 때는 overhead가 발생한다.
class Cat {
private:
public:
Cat()
{
std::cout << "cat constructor" << std::endl;
}
~Cat()
{
std::cout << "cat destructor" << std::endl;
}
private:
int mAge = 10;
};
int divide(int a, int b)
{
if (b == 0)
{
//throw std::exception(); // rvalue로 던진다
throw std::runtime_error("divide by 0");
}
return a / b;
};
void f()
{
//Cat* cp = new Cat();
std::unique_ptr<Cat> cp = std::make_unique<Cat>();
std::cout << divide(10, 0) << std::endl;
// Memory Leak이 발생하게 된다.
// RAII를 준수하자. smart pointer 사용
//delete cp;
}
int cat_divide(int a, int b)
{
if (b == 0)
{
//throw std::exception(); // rvalue로 던진다
throw Cat();
}
return a / b;
};
int main()
{
std::cout << "normal divide" << std::endl;
try
{
std::cout << divide(10, 0) << std::endl;
}
catch (const std::exception &e) // reference로 받아야 한다
{
std::cout << e.what() << std::endl;
std::cout << "exception catched" << std::endl;
}
std::cout << "cat divide" << std::endl;
try
{
std::cout << cat_divide(10, 0) << std::endl;
}
//catch (const Cat & c) // reference로 받아야 한다
catch(...) // ...은 모든 exception을 잡는다
{
std::cout << "cat exception catched" << std::endl;
}
// Memory Leak이 발생하게 된다.
std::cout << "f() divide" << std::endl;
try
{
f();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
|
'C' 카테고리의 다른 글
c++ 상속 public, protected, private 완벽 정리 코드 (0) | 2021.06.29 |
---|---|
c++ exception safety guarantee, exception 주의점, exception을 사용하지 말아야 하는 case (0) | 2021.06.28 |
c++ Union, Variant (0) | 2021.06.28 |
C++ enum class(매우 중요) (0) | 2021.06.28 |
c++ optional (C++17부터 지원) (0) | 2021.06.28 |