다음을 통해 공유


예외: 예외 처리 중 개체 해제

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

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

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

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

위에서 언급한 대로, myPersonSomeFunc에 의해 예외가 발생되면 삭제되지 않습니다. 실행은 다음 외부 예외 처리기로 직접 이동하여 일반 함수 종료 및 개체를 삭제하는 코드를 무시합니다. 예외가 함수를 벗어나면 개체에 대한 포인터가 범위를 벗어나고 프로그램이 실행되는 한 개체가 차지하는 메모리는 복구되지 않습니다. 메모리 누수입니다. 메모리 진단을 사용하면 이 누수를 탐지할 수 있습니다.

예외를 로컬로 처리

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되었음을 결코 알지 못하며 정상적으로 종료하고 개체를 삭제할 기회가 없습니다.

** 개체를 소멸한 후 예외 던지기

예외를 처리하는 또 다른 방법은 예외를 다음 외부 예외 처리 컨텍스트에 전달하는 것입니다. catch 블록에서 로컬로 할당된 개체를 정리한 다음 추가 처리를 위해 예외를 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 블록을 사용하여 예외를 포착하고 생성한 개체를 소멸할 수 있는 기회를 가집니다. 특히 많은 MFC 함수가 예외를 throw할 수 있습니다.

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

참고하십시오

예외 처리