Я не могу спать!:)
У меня есть достаточно большой проект в Windows и столкнулся с некоторыми проблемами с кучей коррупции. Я прочитал все SO, включая эту приятную тему: Как отлаживать ошибки кучи коррупции?, однако ничто не было подходящим, чтобы помочь мне из коробки. Debug CRT
и BoundsChecker
обнаружены повреждения кучи, но адреса всегда были разными, а точка обнаружения всегда находилась далеко от фактической памяти. Я не спал до середины ночи и делал следующий взлом:
DWORD PageSize = 0;
inline void SetPageSize()
{
if ( !PageSize )
{
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
PageSize = sysInfo.dwPageSize;
}
}
void* operator new (size_t nSize)
{
SetPageSize();
size_t Extra = nSize % PageSize;
nSize = nSize + ( PageSize - Extra );
return Ptr = VirtualAlloc( 0, nSize, MEM_COMMIT, PAGE_READWRITE);
}
void operator delete (void* pPtr)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(pPtr, &mbi, sizeof(mbi));
// leave pages in reserved state, but free the physical memory
VirtualFree(pPtr, 0, MEM_DECOMMIT);
DWORD OldProtect;
// protect the address space, so noone can access those pages
VirtualProtect(pPtr, mbi.RegionSize, PAGE_NOACCESS, &OldProtect);
}
Некоторые ошибки повреждения кучи стали очевидными, и я смог их исправить. Больше не было предупреждений об ошибках Debug CRT при выходе. Однако у меня есть некоторые вопросы относительно этого взлома:
1. Может ли он выдавать ложные срабатывания?
2. Может ли он пропустить некоторые из кучи коррупции? (даже если мы заменим malloc/realloc/free?)
3. Он не может работать на 32-битных с OUT_OF_MEMORY
, только на 64-битных. Правильно ли мы просто закончили виртуальное адресное пространство на 32-битных?