if (p&&valid)
{
printf("Блок памяти: %xh", (unsigned int)p );
}
if (!p&&valid) cout<<ATO("Ошибка выделения памяти!\n");
} while (1);
}
Результат работы программы показан на рис. 1.
Рис. 1. Работа примера 1
Пример 2. Определенно одним из основных преимуществ использования VirtualAlloc является возможность управления уровнем доступа к страницам оперативной памяти как во время ее выделения, так и позже (при помощи функции VirtualProtect). Разумное использование этой возможности может существенно упростить разработку многих приложений.
Для примера рассмотрим код в листинге 2. Это библиотечная функция, которая возвращает указатель на статическую строку. В реальной жизни эта функция может располагаться в библиотеке DLL, однако для целей этой программы мы включим ее в состав основного исполняемого файла наряду с функцией main.
Листинг 2. Передача статической строки в режиме только для чтения
#include <stdio.h>
#include <string.h>
#include <windows.h>
extern "C" int printf_oem(const char *s, ... )
{
va_list ap;
va_start(ap,s);
char src[256];
vsprintf(src,s,ap );
va_end(ap);
char oems[256];
CharToOem(src,oems);
return printf(oems);
}
#define printf printf_oem
char *getmsg()
{
static char *msg;
if (msg==NULL)
{
char tmp[1024];
DWORD oldprot;
FILE *f;
f=fopen("strings.txt", "r");
if (!f) return NULL;
fgets(tmp, sizeof(tmp), f);
// Выделяет целую страницу памяти, что приемлемо для данного примера
msg=(char *)VirtualAlloc(NULL, strlen(tmp)+1, MEM_COMMIT, PAGE_READWRITE);
strcpy(msg, tmp);
fclose(f);
// Назначает уровень доступа к странице памяти только для чтения
VirtualProtect(msg, strlen(msg)+1, PAGE_READONLY, &oldprot);
}
return msg;
}
void main()
{
char *m=getmsg();
try {
printf("Вся строка: %s\n",m);
m=strtok(m," \t");
printf("token1=%s\n",m);
m=getmsg();
printf("Вся строка: %s\n",m);
}
catch (...) // следить за любыми исключениями
{
printf("Произошло исключение!\n");
}
getchar(); // ожидание для отладочных целей
}
Результат работы программы показан на рис. 2.
Рис. 2. Работа примера 2
Листинг 3. Бесконечный буфер
#include <windows.h>
#include <stdio.h>
#include <eh.h> // преобразование исключений C в исключения C++
extern "C" int printf_oem(const char *s, ... )
{
va_list ap;
va_start(ap,s);
char src[256];
vsprintf(src,s,ap );
va_end(ap);
char oems[256];
CharToOem(src,oems);
return printf(oems);
}
#define printf printf_oem
#define Kb 1024
void cppexcept( unsigned int u, _EXCEPTION_POINTERS* pExp )
{
throw u;
}
char* getbuffer(long int IpvAddr)
{
char *rv;
rv= (char *)VirtualAlloc((LPVOID) IpvAddr, 32*Kb,MEM_COMMIT,PAGE_READWRITE);
return rv;
}
void freebuffer(char *p)
{
VirtualFree(p,0,MEM_RELEASE);
}
void main()
{
DWORD oldprot;
char *p1=getbuffer(0x900000);
char *p2=getbuffer(0x1000000);
char *p3=getbuffer(0x3000000);
if (p1) printf("\nВыделен блок памяти в 32 Кбайта по адресу: 0x%x",p1);
else printf("\nНевозможно выделить память по адресу 0x900000");
if (p2) printf("\nВыделен блок памяти в 32 Кбайта по адресу: %x",p2);
else printf("\nНевозможно выделить память по адресу 0x1000000");
if (p3) printf("\nВыделен блок памяти в 32 Кбайта по адресу: %x",p3);
else printf("\nНевозможно выделить память по адресу 0x3000000");
for (int i=0;i<32*Kb;i++)
{
if (p1) p1[i]=1;
if (p2) p2[i]=1;
if (p3) p3[i]=1;
}
if (p1) VirtualProtect(p1, 32*Kb, PAGE_READONLY, &oldprot);
if (p2) VirtualProtect(p2, 32*Kb, PAGE_READONLY, &oldprot);
if (p3) VirtualProtect(p3, 32*Kb, PAGE_READONLY, &oldprot);
printf("\n\nЗащита памяти установлена");
_se_translator_function oldhandler=_set_se_translator(cppexcept);
//Попытка обнулить память
printf("\n\nПопытка обнулить память...");
try
{
for (i=0;i<32*Kb;i++)
{
p1[i]=0;
p2[i]=0;
p3[i]=0;
}
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.