C++) RAII란?
RAII
- Resource Acqusition is Initialization. 획득한 자원을 초기화 한다
- C++ 설계 디자인 패턴 중 하나인 키워드
- 자원을 사용하고자 하는 상황에서, 생성자에서 자원 획득을,
소멸자에서 자원 해제를 하는 자원 관리용 클래스를 만드는 프로그래밍 패턴
RAII is a C++ programming technique which binds the life cycle of a resource that must be acquired before use to the lifetime of an object.
- “자원의 생애주기(life cycle, 자원 획득과 자원 해제)를 객체의 생애(lifetime)에 바인딩시키는 기법이다”
- 자원의 생애주기란,
C++ 프로그램에서 자원은 동적 메모리, 쓰레드, 소켓, 파일, 뮤텍스, 데이터베이스 커넥션 등등을 의미 - 이러한 자원을 사용하기 위해서는, 자원을 사용하기 전에 자원을 획득해야 하고,
자원을 다 사용하면 자원을 해제해야 한다
- 자원의 생애주기란,
RAII의 필요성
- 동적 프로그래밍을 위해
new
키워드를 사용해 힙 메모리에서 메모리를 할당받는다- 그러나, 실수나 exception 등으로 할당받은 메모리를 해제하지 못하고 메모리 누수가 발생하거나, mutex에서 lock이 발생하는 경우가 있음
- java, python, C# 과 같은 다른 객체지향 프로그램에서는 런타임이 자원 관리를 돕지만,
C++ 에서는 자동 자원 관리를 해주지 않아, 실력에 의해 메모리 문제가 좌우됨! - 이러한 문제들을 안전하게 관리하고자 만든것들이 RAII
- 객체의 생애는 런타임이 알아서 관리해주기때문에, 이에 맡기는 방법
- 객체의 생성자가 호출될 때 자원을 획득하고,
객체의 소멸자가 호출될 때 자원을 해제한다- exception이 발생하는 경우에도 소멸자는 항상 실행되기 때문에 보장됨
unique_ptr
,shared_ptr
,lock_guard
등- 해당 클래스들은 함수가 끝나면,
{}
중괄호에서 벗어난다면 소멸자를 호출하여
...finally
처럼 무조건 실행함예시
RAII를 적용하지 않은 모델
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
bool error() {
return true;
}
void fnc() {
int* c = new int[100];
// std::unique_ptr<int> q(c);
if (error()) return; //알수 없는 error발생!!
delete[] c; //안써도 알아서 할당 해제를 해준다.
}
int main() {
fnc();
printf("hi");
_CrtDumpMemoryLeaks();
return 0;
}
- fnc함수에서 new 를 통해 메모리를 할당받음
- 그러나 에러가 발생해서
delete[] c;
를 호출하지 못하고 중도에 리턴함 - 메모리 해제가 되지 않아 메모리 누수가 발생함
RAII를 적용한 모델
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
bool error() {
return true;
}
void fnc() {
int* c = new int[100];
std::unique_ptr<int> q(c);
if (error()) return; //알수 없는 error발생!!
delete[] c; //안써도 알아서 할당 해제를 해준다.
}
int main() {
fnc();
printf("hi");
_CrtDumpMemoryLeaks();
return 0;
}
unique_ptr<int>
로 RAII를 적용함- 중도에 에러가 발생하여 명시적으로 메모리 반납을 하는
delete[] c;
를 거치지 않아도,
소멸자가 자동으로 호출되면서 메모리를 반환한다
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.