Проверяет распределенную память. Работает для функции 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. ------
Да, забыл, эта функция определена только в отладочной версии. Я уже много раз говорил, что надо делать :-)