728x90

SEH(Structured Exception Handler)

- Handler : 예외를 처리하는 함수

- SEH : Windows의 예외처리 매커니즘

- 예외 처리의 필요성

FILE* fileptr = fopen("test","r");
if(fileptr == NULL)
{
  // 예외 처리
}

char* dataBuf = (char*)malloc(sizeof(char) * 100);
if(dataBuf == NULL)
{
  // 예외 처리
}

int numOfRead = fread(dataBuf, 1, 10, fileptr);
if(numOfRead != 10)
{
  // 예외 처리
}

    -> 위와 같이 작성되어 있으면 if문이 있을 때 예외 처리를 위한 것일 수 있고 로직의 하나일 수도 있기 때문에 거추장스러울 수 있음

FILE* fileptr = fopen("test","r");
char* dataBuf = (char*)malloc(sizeof(char) * 100);
int numOfRead = fread(dataBuf, 1, 10, fileptr);
// 프로그램의 실제 흐름

if(fileptr == NULL)
{
  // 예외 처리
}
if(dataBuf == NULL)
{
  // 예외 처리
}
if(numOfRead != 10)
{
  // 예외 처리
}
// 예외 처리 영역 분리

    -> 그렇기 때문에 프로그램에 실제 흐름과 흐름에 따른 예외처리 영역을 분리함

    -> SEH를 사용하면 실제 흐름과 예외 처리 영역을 나눌 수 있음

 

예외와 에러의 차이점

- 컴파일 타임 오류(문법적 구문 오류) : 에러 

    -> 치명적이고 실수적인 성격이 강함

    -> 반드시 고쳐야 실행이 됨

- 런타임 오류 : 일반적으로 예외

    -> 소프트웨어에서 정한 상황, 가정을 벗어난 것을 예외라고 함

    -> 좋은 소프트웨어는 예외가 발생했을 때 종료가 되지 않게 처리를 잘 해줘야 함

 

종료 핸들러(Termination Handler)

- SEH가 제공하는 핸들러 중 하나이며 예외 핸들러의 확장

- __try, __finally 블럭으로 구성

- __try 블럭에 코드가 한줄이라도 실행됐다면 __finally 블럭이 실행이 되어야 함

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int _tmain(int argc, TCHAR* argv[])
{
	int a, b;

	__try
	{
		_tprintf(_T("input divide string [ a/b ] : "));
		_tscanf(_T("%d / %d"), &a, &b);

		if (b == 0)
			return -1;
	}
	__finally
	{
		_tprintf(_T("__finally block !\n"));
	}
	return 0;
}

    -> return 을 하더라도 finally 블럭을 한번 실행함

- 종료 핸들러 활용

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int _tmain(int argc, TCHAR* argv[])
{
	__try
	{
		fptr = _tfopen(_T("string.dat"), _T("r"));

		if (fptr == NULL)
			return -1;
	}
	__finally
	{
		if (fptr != NULL)
			fclose(fptr);
	}
	return 0;
}

    -> 예외적인 상황이 발생했을 때 바로 return으로 프로그램이 종료되어도 finally 블럭 안에 있는 코드를 실행하여 안정적임

728x90

+ Recent posts