예외: 예외의 개체 해제
이 문서에서는 예외가 발생할 때 개체를 해제하는 방법 및 필요성에 대해 설명합니다. 다룰 주제는 다음과 같습니다.
프레임워크 또는 애플리케이션에서 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 및 삭제를 참조 하세요.