예외: 예외의 개체 해제

이 문서에서는 예외가 발생할 때 개체를 해제하는 방법 및 필요성에 대해 설명합니다. 다룰 주제는 다음과 같습니다.

프레임워크 또는 애플리케이션에서 throw된 예외는 일반 프로그램 흐름을 중단합니다. 따라서 예외가 throw되는 경우 개체를 올바르게 삭제할 수 있도록 개체를 면밀히 추적하는 것이 매우 중요합니다.

이 작업을 수행하는 두 가지 기본 방법이 있습니다.

  • 및 키워드(keyword) 사용하여 로컬에서 try catch 예외를 처리한 다음 하나의 문으로 모든 개체를 삭제합니다.

  • 추가 처리를 위해 블록 외부에 catch 예외를 throw하기 전에 블록의 모든 개체를 삭제합니다.

이러한 두 가지 방법은 다음과 같은 문제가 있는 예제에 대한 솔루션으로 아래에 설명되어 있습니다.

void SomeFunc()        // Problematic code
{
   CPerson* myPerson = new CPerson;

   // Do something that might throw an exception.
   myPerson->SomeFunc();

   // Now destroy the object before exiting.
   // If SomeFunc above throws an exception this code will
   // not be reached and myPerson will not be deleted.
   delete myPerson;
}

위에서 myPerson 작성한 대로 예외가 throw SomeFunc된 경우 삭제되지 않습니다. 실행은 다음 외부 예외 처리기로 직접 이동하여 일반 함수 종료 및 개체를 삭제하는 코드를 무시합니다. 예외가 함수를 벗어나면 개체에 대한 포인터가 범위를 벗어나고 프로그램이 실행되는 한 개체가 차지하는 메모리는 복구되지 않습니다. 메모리 누수입니다. 메모리 진단 사용하여 검색됩니다.

예외를 로컬로 처리

try/catch 패러다임은 메모리 누수 방지 및 예외 발생 시 개체가 제거되도록 하는 방어 프로그래밍 방법을 제공합니다. 예를 들어 이 문서의 앞부분에 나와 있는 예제를 다음과 같이 다시 작성할 수 있습니다.

void SomeFunc()
{
   CPerson* myPerson = new CPerson;

   try
   {
      // Do something that might throw an exception.
      myPerson->SomeFunc();
   }
   catch (CException* e)
   {
      // Handle the exception locally
      e->Delete();
   }

   // Now destroy the object before exiting.
   delete myPerson;
}

이 새 예제에서는 예외를 catch하고 로컬로 처리하도록 예외 처리기를 설정합니다. 그런 다음 함수를 정상적으로 종료하고 개체를 삭제합니다. 이 예제의 중요한 측면은 try/catch 블록을 사용하여 예외를 catch하는 컨텍스트가 설정된다는 것입니다. 로컬 예외 프레임이 없으면 함수는 예외가 throw되었음을 결코 알지 못하며 정상적으로 종료하고 개체를 삭제할 기회가 없습니다.

개체를 삭제한 후 예외 throw

예외를 처리하는 또 다른 방법은 예외를 다음 외부 예외 처리 컨텍스트에 전달하는 것입니다. catch 블록에서 로컬로 할당된 개체의 일부 클린 작업을 수행하고 추가 처리를 위해 예외를 throw할 수 있습니다.

throw 함수는 힙 개체의 할당을 취소할 수도 있으며 그렇지 않을 수도 있습니다. 함수가 항상 일반 사례에서 반환하기 전에 힙 개체의 할당을 취소하는 경우 함수는 예외를 throw하기 전에 힙 개체의 할당을 취소해야 합니다. 반면 함수가 일반 사례에서 반환하기 전에 일반적으로 개체의 할당을 취소하지 않는 경우 힙 개체의 할당을 취소해야 하는지 여부를 대/소문자별로 결정해야 합니다.

다음 예제에서는 로컬로 할당된 개체를 클린 수 있는 방법을 보여줍니다.

void SomeFunc()
{
   CPerson* myPerson = new CPerson;

   try
   {
      // Do something that might throw an exception.
      myPerson->SomeFunc();
   }
   catch (CException* e)
   {
      e->ReportError();
      // Destroy the object before passing exception on.
      delete myPerson;
      // Throw the exception to the next handler.
      throw;
   }

   // On normal exits, destroy the object.
   delete myPerson;
}

예외 메커니즘은 프레임 개체의 할당을 자동으로 취소합니다. 프레임 개체의 소멸자도 호출됩니다.

예외를 throw할 수 있는 함수를 호출하는 경우 try/catch 블록을 사용하여 예외를 catch하고 만든 개체를 삭제할 수 있는지 확인할 수 있습니다. 특히 많은 MFC 함수가 예외를 throw할 수 있습니다.

자세한 내용은 예외: 예외 Catch 및 삭제를 참조 하세요.

참고 항목

예외 처리