Шаг 234 - AfxCheckMemory

Проверяет распределенную память. Работает для функции new, но не определяет для функций прямого распределения памяти Windows типа malloc или GlobalAlloc.

BOOL AfxCheckMemory( );

Дело в том, что при распределении памяти к самой памяти дополнительно есть байт защиты с информацией о ней. Так вот, если он будет испорчен в результате каких-либо действий, то эта функция сработает. Этот байт находится перед указателем на память. Вот код:

#include "stdafx.h"
#include "afxwin.h"

class Cb
{
public:
	Cb();
	~Cb();
private:
	char* b;
};

Cb::Cb()
{ b = new char; }

Cb::~Cb()
{delete b;}

void main()
{
	Cb* cClassB;
	cClassB = new Cb;
	*(((char *)cClassB)-1)=99;
	afxDump << "------\n";
	AfxCheckMemory();
	afxDump << "------\n";
	delete cClassB;
}

Эта загадочная надпись *(((char *)cClassB)-1)=99; говорит вот о чем. Мы идем от указателя на объект на один байт назад, но для этого сначала приводим его к указателю типа char для передвижения на один байт, после чего передвигается и значение, которое мы разыменовываем и присваиваем другое. Понятно ??? Нет, тогда по шагам.

 ((char *)cClassB)   	теперь это указатель на char* !!!!!!!
 -1  			на один char назад, чтобы зайти указателем на байт защиты
 *()			получить значение по указателю
 =99			присвоить 99 этому значению 		

В окне отладки Вы увидите вот что:

------
memory check error at 0x00770D1F = 0x63, should be 0xFD.
DAMAGE: before Normal block (#21) at 0x00770D20.
Normal located at 0x00770D20 is 4 bytes long.
------

Если вы запустите программу, то все равно получите сообщение об ошибке !!! Тогда зачем эта функция нужна ??? Но вы получите сообщение об ошибке только в момент когда эта память будет удаляться. Вот пример. Ошибка уже есть, но программа работает как небывало и выводит диалоговое окно (например) !!!

void main()
{
	Cb* cClassB;
	cClassB = new Cb;
	*(((char *)cClassB)-1)=99;
	afxDump << "------\n";
//	AfxCheckMemory();
	afxDump << "------\n";
	AfxMessageBox("Error ???");
	delete cClassB;
}

А вот в таком варианте вы получите сообщение сразу:

afxDump << "------\n";
ASSERT(AfxCheckMemory());
afxDump << "------\n";

Думаю теперь понятно. В любой момент Вы можете проверить Вашу динамическую память выделенную new на предмет ее повреждения какими-нибудь операциями.

Вы можете получить более подробную информацию используя DEBUG_NEW, вот как она выглядит:

------
memory check error at 0x00770D1F = 0x63, should be 0xFD.
DAMAGE: before Normal block (#21) at 0x00770D20.
Normal allocated at file E:\PROJECT\TestObject\TestObject.cpp(32).
Normal located at 0x00770D20 is 4 bytes long.
Loaded 'C:\WINDOWS\SYSTEM\INDICDLL.DLL', no matching symbolic information found.
------

Да, забыл, эта функция определена только в отладочной версии. Я уже много раз говорил, что надо делать :-)


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