더북(TheBook)

우리가 고품질 과학 소프트웨어를 작성할 때 낭비되는 메모리가 현재 사용 중인 애플리케이션에 중요하지 않더라도 메모리 누수를 용인할 수는 없다. 많은 사람이 우리 소프트웨어를 사용하고 있을 때 조만간 누군가가 우리를 비판하고 결국 다른 사람들이 우리 소프트웨어를 사용하지 않게 될 것이다. 다행히 B.3절에서 설명한 것처럼 메모리 누수를 찾는 데 도움이 되는 도구들이 있다.

포인터로 시연했던 문제는 재미없게 하려는 의도가 아니다. 그리고 포인터를 사용하지 말라고 권하는 것도 아니다. 포인터를 사용해 리스트, 큐, 트리, 그래프 등과 같이 많은 작업을 수행할 수 있다. 그러나 위에서 언급했던 모든 심각한 문제를 피하려면 포인터는 조심스럽게 사용해야 한다.

포인터 관련 오류를 최소화하는 전략은 세 가지가 있다.

표준 컨테이너를 사용하라: 표준 라이브러리나 유효성이 검증된 라이브러리를 사용하라. 표준 라이브러리의 std::vector는 크기 조정 및 범위 검사를 포함한 동적 배열의 모든 기능을 제공하며 메모리를 자동으로 해제한다.

캡슐화: 클래스에서의 동적 메모리 관리. 따라서 클래스당 한 번만 처리해야 한다.* 개체를 소멸할 때 개체가 할당한 모든 메모리를 해제하면 메모리 할당 빈도는 더 이상 중요하지 않다. 만약 우리가 738개의 개체를 동적 할당했다면 738번 해제할 것이다. 메모리는 개체 생성 시 할당하고 파괴 시 해제해야 한다. 이러한 원칙을 RAII(Resource Acquisition Is Intialization)라고 한다. 반대로 우리가 부분적으로 반복문과 조건문에서 new를 738번 호출했다면 delete를 정확하게 738번 호출했는지 확인할 수 있겠는가? 우리는 이를 위한 도구가 있음을 알고 있다.* 그러나 오류를 수정하는 것보다 예방하는 게 더 낫다. 물론 캡슐화 아이디어가 나쁜 아이디어는 아니지만 프로그램 전체에 (원시) 포인터를 뿌리는 아이디어보다는 그다지 효과적이지 않다. 2.4.2.1절에서 RAII에 대해 더 자세히 알아볼 것이다.

스마트 포인터를 사용하라: 이에 대해서는 다음 절(1.8.3절)에서 설명할 것이다.

 

* 이 도구는 현재 실행에 오류가 없지만 입력이 달라지면 결과도 달라질 수 있음을 보여준다.

 

* 클래스보다 많은 개체가 있다고 가정하는 것이 안전하다. 그렇지 않다면, 프로그램 디자인 전반에 문제가 있다고 볼 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.