Шаг 295 - Метод обработки исключений SEH и MFC

Посмотрите "Шаг 46 - Структурная обработка исключений - SEH" для выяснения некоторых тонкостей. Давайте создадим простое приложение MFC типа SDI. Дадим имя этому приложению TestSEH и встроим обработку нажатия на кнопку мыши в класс вида.

//////////////////////////////////////
// CTestSEHView message handlers

void CTestSEHView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	LPVOID lpOb=NULL;
	__try
	{
		lpOb=VirtualAlloc(NULL,1024,MEM_COMMIT,PAGE_READWRITE);
		if (lpOb!=NULL) TRACE(" Memory Alloc \n");
		return;
	}
	__finally
	{
		if (lpOb!=NULL) 
		{
			VirtualFree(lpOb,MEM_RELEASE | MEM_DECOMMIT,PAGE_READWRITE);
			TRACE(" Memory Free \n");
		}
	}
	
	CView::OnLButtonDown(nFlags, point);
}

Запустим в режиме отладки (F5). Щелкнем два раза и посмотрим окно отладчика.

Loaded 'C:\WINDOWS\SYSTEM\INDICDLL.DLL', no matching symbolic information found.
 Memory Alloc 
 Memory Free 
 Memory Alloc 
 Memory Free 
The thread 0xFFF8EA67 has exited with code 0 (0x0).

Как видим освобождение памяти вызывается всегда. Вся прелесть данного примера, что по return мы должны были покинуть функцию, но этого не произошло до освобождения памяти. Вот в этом суть. Помните пример из "Шаг 99 - Частная куча для нашего класса" ?

Надо предусматривать, что будет при исключении с объектом. Вся прелесть нового способа в том, что память все равно будет освобождена и делаем мы это в одном месте __ finally. Смотрите простой пример. Вызов return приведет к окончанию программы и никакой обработчик не будет вызван.

#include "stdafx.h"
#include "iostream.h"

void main()
{
	try
	{
		return;
		cout << "return" << endl;
		throw;
	}
	catch(...)
	{
		cout << "Catch" << endl;
	}
	cout << "Finish" << endl;
}

Вызов return просто не обработан в try, вот теперь как говорилось в некоторой рекламе "почувствуйте разницу".

И еще некоторый момент при выполнении вот такой программы со структурной обрабокой появится окно о том, что программа выполнила некорректную операцию, но все равно код окончания будет выполнен.

#include "stdafx.h"
#include "iostream.h"

void main()
{
	__try
	{
		int x=0;
		int y=1;
		int z=y/x;
		
	}
	__finally
	{
		cout << "Error Detecting" << endl;
	}
}

А вот при такой программе окна о некорректной операции не будет:

#include "stdafx.h"
#include "iostream.h"

void main()
{
	try
	{
		int x=0;
		int y=1;
		int z=y/x;
	}
	catch(...)
	{
		cout << "Error Detecting" << endl;
	}
}

Так вот вывод некоторый непонятный напрашивается. Помните окна о не корректной операции в Windows, ну Вы их часто встречаете :-). Так либо программисты не пользуются обработкой исключительных ситуаций, толи пользуются структурной обработкой не особенно совместимой с классами и MFC. Так что, если есть мысли по этому поводу пишите буду рад опубликовать.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 2.01.2001