下面程序是一個數組,預定了內存,但是沒有分配物理內存。利用異常處理不可訪問,當寫入數據時,會觸發異常,然後申請內存,這樣就節省了內存使用率
// SEH.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <assert.h>
#include <Strsafe.h>
typedef struct MyTest
{
char name[10];
int age;
}CELL,*PCELL;
const int g_h = 1024;
const int g_l = 512;
int g_len = 1024 * 512;
typedef CELL MyStruct[g_h][g_l];
MyStruct* pMyTest = NULL;
void Init(PBYTE* pData, DWORD dwsize)
{
*pData =(PBYTE)VirtualAlloc(NULL, dwsize,
MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);
assert(NULL != pData);
}
LONG ExceptionFilter(PEXCEPTION_POINTERS pep, DWORD dwSize)
{
// Default to trying another filter (safest thing to do)
LONG lDisposition = EXCEPTION_EXECUTE_HANDLER;;
// We only fix access violations
if (pep->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
return(EXCEPTION_CONTINUE_EXECUTION);
// Get address of attempted access and get attempted read or write
PVOID pvAddrTouched = (PVOID) pep->ExceptionRecord->ExceptionInformation[1];
BOOL bAttemptedRead = (pep->ExceptionRecord->ExceptionInformation[0] == 0);
void* pAddress = pMyTest;
// Is attempted access within this VMArray's reserved region?
if ((pAddress <= pvAddrTouched) &&
(pvAddrTouched < ((PBYTE) pAddress + dwSize))) {
TCHAR sz[200];
StringCchPrintf(sz, _countof(sz), TEXT("Violation: Attempting to %s"),
bAttemptedRead ? TEXT("Read") : TEXT("Write"));
printf("%S\n",sz);
if (!bAttemptedRead)
{
BOOL bCommittedStorage = FALSE; // Assume committing storage fails
do {
bCommittedStorage = (NULL != VirtualAlloc(pvAddrTouched,
sizeof(CELL), MEM_COMMIT, PAGE_READWRITE));
if (!bCommittedStorage ) {
MessageBox(NULL,
TEXT("Please close some other applications and Press OK."),
TEXT("Insufficient Memory Available"), MB_ICONWARNING | MB_OK);
}
} while (!bCommittedStorage);
lDisposition = (bCommittedStorage
? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER);
}
}
return(lDisposition);
}
static LONG WINAPI MYhandledExceptionFilter(PEXCEPTION_POINTERS pep) {
MessageBoxA(NULL,"1","1",MB_OK);
return EXCEPTION_EXECUTE_HANDLER;
}
int _tmain(int argc, _TCHAR* argv[])
{
// HMODULE hmudule = LoadLibrary("kernel32.dll");
// PUNHANDLEDEXCEPTIONFILTER = (PUNHANDLEDEXCEPTIONFILTER)GetProcAddress(hmudule,
// "");
SetUnhandledExceptionFilter(MYhandledExceptionFilter);
int i = 0;
strlen(NULL);
int j = 10 / i;
Init((PBYTE*)&pMyTest,g_len);
__try
{
int a = (*pMyTest)[0][0].age;
}
__except(ExceptionFilter(GetExceptionInformation(),g_len))
{
printf("111\n");
}
__try
{
(*pMyTest)[0][0].age = 10;
(*pMyTest)[0][1].age = 11;
(*pMyTest)[0][2].age = 11;
}
__except(ExceptionFilter(GetExceptionInformation(),g_len))
{
printf("222\n");
}
getchar();
return 0;
}