Причины такого рода ошибок могут быть разными:
- Вы пытаетесь освободить с помощью
SysFreeString
память, которая выделена не с SysAllocString
, а, например, с CoTaskMemAlloc
. - У вас правильная куча.
Повреждения кучи трудно локализовать.Функция HeapSetInformation
может быть очень полезна.Например, вы можете использовать
HeapSetInformation(NULL,HeapEnableTerminationOnCorruption,NULL,0);
Другим хорошим способом является использование функции HeapValidate
.Например, вы можете определить функцию, которая проверяет все кучи процесса (код на C, который может быть легко переписан на Delphi):
BOOL MyHeapValidate (void)
{
HANDLE hProcessHeaps[1024];
DWORD i;
DWORD dwNumberOfHeaps;
BOOL bSuccess = FALSE;
dwNumberOfHeaps = GetProcessHeaps (sizeof(hProcessHeaps)/sizeof(hProcessHeaps[0]),
hProcessHeaps);
if (dwNumberOfHeaps > sizeof(hProcessHeaps)/sizeof(hProcessHeaps[0])) {
MessageBox(NULL, TEXT("GetProcessHeaps()"),
TEXT("Error in MyHeapValidate()"), MB_OK);
return FALSE;
}
for (i=0; i<dwNumberOfHeaps; i++) {
bSuccess = HeapValidate (hProcessHeaps[i], 0, NULL);
if (!bSuccess)
return bSuccess;
}
return bSuccess;
}
Использование этой функции может быть следующим:
void BadFunction(BSTR bstr)
{
LPOLESTR psz = OLESTR("Test12");
lstrcpy (bstr, psz);
}
int main()
{
LPOLESTR psz = OLESTR("Test");
BSTR bstr = SysAllocString (psz);
// verify that before call of BadFunction() all process heaps are OK!
if (!MyHeapValidate()) {
_tprintf(TEXT("heap is corrupted after the step 1.\n"));
return 1;
}
BadFunction(bstr);
if (!MyHeapValidate()) {
_tprintf(TEXT("heap is corrupted after the step 1.\n"));
return 1;
}
SysFreeString (bstr);
return 0;
}
В отношении вставки MyHeapValidate()
в разные подозрительные места вы можете очень быстро определить место повреждения.