虚拟内存一次保留(MEM_RESERVE 可以理解为申请)最小就是 64K,一次提交(MEM_COMMIT)至少是一个页面 4K。而往往有的时候我们不知道我们到底需要多少虚拟内存才够使用,所以可能需要动态分配,下面例子演示了如何使用结构化异常机制,动态根据需要分配内存给一个不断写入新字符的空间使用。例子来自 MSDN,我只是学习抄写了一份!
代码语言:javascript复制#include <tchar.h>
#include <windows.h>
#define PAGELIMIT 80
LPTSTR lpNxtPage; // 用于记录已经提交的虚拟内存的位置
DWORD dwPages = 0; // 限制次数
DWORD dwPageSize; // 储存系统页面大小的变量
int PageFaultExceptionFilter(DWORD dwCode)
{
LPVOID lpvResult;
// 如果进程不是访问了错误的虚拟内存地址,直接返回
if (dwCode != EXCEPTION_ACCESS_VIOLATION)
{
return EXCEPTION_EXECUTE_HANDLER;
}
// 如果超出了页面限制,直接返回
if (dwPages > PAGELIMIT)
{
return EXCEPTION_EXECUTE_HANDLER;
}
// 为程序分配内存
lpvResult = VirtualAlloc((LPVOID)lpNxtPage, dwPageSize, MEM_COMMIT, PAGE_READWRITE);
if (NULL == lpvResult)
{
return EXCEPTION_EXECUTE_HANDLER;
}
// 限制变量自增
dwPages ;
// 让已提交内存位置后移
lpNxtPage = dwPageSize;
// 让程序继续执行
return EXCEPTION_CONTINUE_EXECUTION;
}
void main(void)
{
LPVOID lpvBase;
LPTSTR lpPtr;
BOOL bSuccess;
DWORD i;
SYSTEM_INFO sSysInfo;
GetSystemInfo(&sSysInfo);
dwPageSize = sSysInfo.dwPageSize;
lpvBase = VirtualAlloc(NULL, PAGELIMIT * dwPageSize, MEM_RESERVE, PAGE_NOACCESS);
lpPtr = lpNxtPage = (LPTSTR)lpvBase;
for (i = 0; i < PAGELIMIT * dwPageSize; i )
{
__try
{
// 尚未分配内存就给赋值会触发异常
lpPtr[i] = 'a';
}
__except (PageFaultExceptionFilter(GetExceptionCode()))
{
ExitProcess(GetLastError());
}
}
bSuccess = VirtualFree(lpvBase, 0, MEM_RELEASE);
}
void ErrorExit(LPTSTR lpMsg)
{
_tprintf(_T("Error! %s with error code of %ldn"), lpMsg, GetLastError());
exit(0);
}