본문 바로가기
프로그래밍/C++

C++] RAII란?

by Hwan2 2020. 6. 13.
728x90
반응형

1. RAII란?

RAII는 Resource acquisition is initialization의 약자로 직여해보면 "자원 흭득을 초기화한다."라고 해석이 됩니다.

즉, "흭득된 자원을 초기화 한다."라고 생각하시면 됩니다.


그럼 RAII는 뭐냐? 키워드냐? 클래스냐? 함수냐??

RAII는 C++설계 패턴중 하나인 키워드입니다.

이러이러한 식의 설계를 RAII라고 부르자고 된것입니다.


그럼 여기서 말하는 이러이러한 식의 설계는 무엇일까? 

동적인 프로그래밍을 위해 new라는 키워드를 사용해 힙 메모리에서 메모리를 할당받습니다.

할당 받는순간 해당 메모리의 resource를 프로그래머는 직접 관리하게 됩니다. 

해당 메모리 공간을 잘 활용한다면 정말 좋겠지만, 요놈의 실수, 예기치 못한 exception등...

다양한 이유로 인해 할당받은 메모리를 해제하지 못하고 Memory leak이 발생하게 됩니다.

뿐만 아니라 mutex의 lock에서도 발생할 수 있습니다.


이러한 문제들을 안전하게 관리하고자 만든 것들이 unique_ptr, shared_ptr, lock_guard 등...이 있습니다.

해당 클래스들은 함수가 끝나면, {}(중괄호)에서 벗어 난다면.... finally처럼 무조건 실행해줍니다.

이렇게 함수가 끝나면 무조건 실행을 보장해주는 클래스들의 기능적인 부분들을 통틀어 RAII라고 부르기도 합니다.



2. 예시

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;
}


해당코드는 delete[] c를 만나기전에 함수가 return되는 예시 입니다.


fnc함수가 끝났음에도 불구하고 c에 할당된 메모리는 해제가 안됐습니다.


동일한 조건으로 RAII인 unique_ptr로 해보겠습니다.


bool error() {
    return true;
}

void fnc() {
    int* c = new int[100];
    std::unique_ptr<intq(c);
    if (error()) return;    //알수 없는 error발생!!
    delete[] c;    //안써도 알아서 할당 해제를 해준다.
}

int main() {
    fnc();
    printf("hi");
    _CrtDumpMemoryLeaks();
    return 0;
}


unique_ptr로 했을 경우에는 fnc() 함수가 return됨과 동시에 메모리 해제가 된걸 확인할 수 있습니다.

또한 delete를 굳이 안해줘도 함수에서 벗어나면 자동으로 해제를 해주게 됩니다.

이러한 매커니즘을 RAII라고 하는 겁니다.




mutex의 lock()에서도 RAII를 찾아볼 수 있는데


void fnc() {
    std::mutex m;
    m.lock();
    sum += num;
    //m.unlock();
}


이렇게 .unlock()을 빼버리개 되면 해당 함수의 sum부분은 계속 lock()이 걸린체 실행되게 되고,

다른 Thread들은 해당 함수에 접근을 못하고 wait상태가 되며 프로그램에 심각한 버그를 야기할 수 있습니다.

아니면 .unlock()을 적어놔도 함수 중간에 exception이나 return될 수도 있죠.


때문에 std::unique_lock<std::mutex> std::lock_guard<std::mutex>를 통해 스마트 포인터와 같이 함수가 끝나면 자동으로 .unlock()을 해줄 수 있습니다.



void fnc() {
    std::mutex m;
    std::lock_guard<std::mutex> lock(m);   
    //std::unique_lock<std::mutex> lock(m);
    sum += num;

}


이렇게 말이죠!!

반응형

댓글


스킨편집 -> html 편집에서