C++경우, 프로그램 상에서 한번 획득한 자원은 직접 해제해주지 않는 이상 프로그램이 종료되기 전까지 영원히 남아있게 됨
(프로그램이 종료되면 운영체제가 알아서 해제해줌)
만약 프로그래머가 delete(메모리 해제)를 까먹는다면 메모리 누수가 발생하게 됨.
프로그래머에게 자원 해제에 대한 책임을 묻는다?
→ 예외가 발생한 상황 같은 경우 메모리 누수를 피할 수 없는 상황이 발생한다.
획득된 자원을 초기화 한다.
함수 내부에서 예외가 발생해서 소멸자가 호출하는 코드에 도달하지 못하더라도, 해당 함수의 스택에 정의되어 있는 모든 객체들은 빠짐없이 소멸자가 호출된다. (stack unwinding)
만약 이 소멸자들 안에 다 사용한 자원을 해제하는 루틴을 넣으면?
A* pa = new A();
예를 들어, 위의 포인터 pa의 경우, 객체가 아니므로 소멸자가 호출되지 않는다. 그 대신, pa를 일반적인 포인터가 아닌, 포인터 ‘객체’로 만들어서 소멸될 때 자신이 가리키고 있는 객체가 delete 되도록하게 만들면, 자원(메모리) 관리가 스택의 객체(포인터 객체)를 통해 수행하게 된다.
→ 이런 방식의 포인터 객체를 **스마트 포인터(smart pointer)**라고 한다.
C++에서 메모리를 잘못된 방식으로 관리했을 때 크게 두 가지 종류의 문제점이 발생할 수 있음
메모리를 사용한 후에 해제하지 않은 경우 (memory leak)
간단한 프로그램의 경우 크게 문제될 일이 없지만, 서버처럼 장시간 작동하는 프로그램의 경우 시간이 지남에 따라 점점 사용하는 메모리 양이 늘어나서 결과적으로 나중에 시스템 메모리가 부족해져서 서버가 죽어버리는 상황이 발생할 수 있음
이 문제는 RAII 패턴을 사용하면 해결할 수 있음
이미 해제된 메모리를 다시 참조하는 경우
Data* data = new Data();
Data* data2 = data;
// data의 입장 : 사용 다 했으니 소멸시켜야지
delete data;
// ...
// data2의 입장 : 나도 사용 다 했으니 소멸시켜야지
delete data2;
위 경우 data와 data2가 동시에 한 객체를 가리키고 있는데, delete data를 통해 객체를 소멸 시켜 줬음. 근데 data2가 이미 소멸된 객체를 다시 소멸시키려고 하면 메모리 오류가 나면서 프로그램이 죽게됨. → 이렇게 이미 소멸된 객체를 다시 소멸시켜서 발생하는 버그를 double free 버그라고 부름
위와 같은 문제가 발생한 이유는 만들어진 객체의 소유권이 명확하지 않아서.
만약에, 우리가 어떤 포인터에 객체의 유일한 소유권을 부여해서, 이 포인터 말고는 객체를 소멸 시킬 수 없다! 라고 한다면, 위와 같이 같은 객체를 두 번 소멸 시켜버리는 일은 없을 것이다.
여기부터 무슨말인지 잘 모르겟…