반응형
C++을 사용하여 프로그램을 하다보면 핸들을 많이 다루게 됩니다. 특히 I/O 관련 작업을 할 때나 윈도우 API를 사용할 때 파일을 비롯한 각종 핸들(HANDLE)을 사용하게 됩니다. 이 때 다 사용한 핸들을 닫아주지 않으면 핸들 관련 누수(Leak)가 생기게 됩니다.
이럴 경우 unique_ptr을 이용하여 구간에서만 핸들을 사용하고 다 사용한 후에는 자동으로 핸들을 자동으로 닫게하면 위에서 말한 문제가 일어날 가능성이 적어지게 됩니다.
아래 예제 코드를 살펴보겠습니다.
#include <iostream>
#include <cstdio>
using namespace std;
struct FileCloser {
void operator()(FILE* file) const {
if (file) {
fclose(file);
std::cout << "File closed.\n";
}
}
};
typedef std::unique_ptr<FILE, FileCloser> ScopeHandle;
int main(int argc, char* argv[])
{
FILE* file = nullptr;
fopen_s(&file, "test.txt", "w");
if (!file) {
std::cerr << "Failed to open file.\n";
return 1;
}
ScopeHandle filePtr(file);
fprintf(filePtr.get(), "Hello, world!\n");
// 파일 핸들이 범위를 벗어나면 자동으로 닫힘
return 0;
}
실행 결과는 아래와 같습니다.
File closed.
소스 코드는 간단한 예제를 위하여 C 라이브러리의 FILE을 예제로 보여주었습니다. 예제에서 unique_ptr을 사용하여 ScopeHandle을 정의하여 사용하였습니다. unique_ptr에 템플릿 인자 2 개 주는 것이 조금 어색해 보일 수 있는데 2번째 인자는 해당 객체에 대한 삭제자(delete)라고 보시면 됩니다. 삭제자는 리소스 해제 과정의 커스터마이징에 사용된다고 보시면 됩니다. 이 예제에서는 operator()(File* file)가 unique_ptr이 가지고 있는 객체의 포인터를 파라메터로 하여 호출된다고 보시면 됩니다.
예제 코드에서 file에 대한 핸들을 ScopeHandle가 관리하게 하여 함수가 끝나면 자동으로 파일을 close하게 만들었습니다.
예제에서는 C 라이브러리의 FILE을 이용하였지만 조금만 수정하면 윈도우 API의 각종 HANDLE에 대해서도 응용할 수 있습니다.
반응형
'C++ 프로그래밍' 카테고리의 다른 글
C++ system_clock을 이용하여 64bit tick값 저장 및 로드 예제 (0) | 2022.03.28 |
---|---|
C++ 람다를 활용하여 함수 내 중복 코드 줄이기 (0) | 2022.03.23 |
C++ 람다 사용시 변수 캡처 주의점과 shared_ptr의 활용 (0) | 2022.01.21 |
C++ string_view의 이해와 활용 (0) | 2022.01.15 |
C++ 클래스 함수 간접 호출 : mem_fn, bind, bind_front (0) | 2021.12.11 |
C++ 전역 객체 혹은 정적 객체 간의 생성 및 소멸 순서 문제 (0) | 2021.12.09 |
C++ using namespace를 헤더 파일에 사용하지 말자 (0) | 2021.12.01 |
C++ 람다에서 참조 값과 복사 값 동시에 사용하기 (0) | 2021.11.29 |