VirtualAlloc(p, MEGABYTE, MEM_COMMIT, PAGE_READWRITE);
break;
case '4':
exit(0);
default:
cout<<"\nЧего-чего?\n";
valid=0;
}
if (p&&valid)
cout<<"Блок памяти @ "<<hex<<(unsigned int)p<<"\n";
if (!p&&valid) cout<<"Ошибка выделения памяти!\n";
} while (1);
}
В появившемся меню выберите пункт 1. Программа выделит блок памяти установленного размера, а затем освободит его. На большинстве современных компьютеров эта процедура будет выполнена в течение всего нескольких секунд. За это время Windows должна настроить все необходимые записи в таблице соответствия страниц, определить доступный объем физической памяти и создать необходимое количество страниц виртуальной памяти. Если объем физической памяти вашего компьютера превышает 75 Мбайт, для наглядности попробуйте использовать блок памяти большего размера. Выберите пункт 1 несколько раз, чтобы получить представление о том, насколько быстро выполняется процедура выделения и освобождения достаточно больших участков памяти.
Теперь попробуйте выбрать пункт 2. При этом программа не будет выделять физическую или виртуальную память объемом 64 Мбайт, а лишь зарезервирует диапазон адресов необходимого размера. Это происходит настолько быстро, что вы даже не сможете заметить, что что-либо произошло. Конечно, если вы зарезервировали диапазон адресов, это не значит, что вы сможете немедленно приступить к использованию соответствующей памяти.
Чтобы проверить, как выполняются процедуры резервирования адресов и выделения конкретной памяти в комплексе, выберите пункт 3. При этом программа резервирует адресное пространство указанного объема, а затем выделяет всего один мегабайт памяти из этого адресного пространства. Таким образом, моделируется ситуация, в которой вы на всякий случай резервируете достаточно большой участок непрерывной памяти, однако используете лишь небольшой фрагмент этого участка. Такое поведение, в частности, напоминает работу программы, оцифровывающей видеосигнал, о которой мы говорили ранее. Выбрав пункт 3 тестовой программы, вы заметите, что резервирование адресного пространства и последующее выделение памяти в этом пространстве выполняются фактически мгновенно. Естественно, ведь выделяется лишь один мегабайт из шестидесяти четырех. В большинстве ситуаций, используя подобный подход, вы сможете добиться более гладкой работы ваших программ. Другими словами, если вы зарезервируете 10 Мбайт, а затем выделите всю эту память последовательно блоками по одному мегабайту, у пользователя возникнет ощущение, что ваша программа работает быстрее, чем если бы было выполнено выделение всех 10 Мбайт за одну операцию.
Работа с атрибутами страниц
Определенно одним из основных преимуществ использования VirtualAlloc является возможность управления уровнем доступа к страницам оперативной памяти как во время ее выделения, так и позже (при помощи функции VirtualProtect). Разумное использование этой возможности может существенно упростить разработку многих приложений.
Для примера рассмотрим код в листинге 2. Это библиотечная функция, которая возвращает указатель на статическую строку. В реальной жизни эта функция может располагаться в библиотеке DLL, однако для целей этой программы мы включим ее в состав основного исполняемого файла наряду с функцией main.
Листинг 2. Передача статической строки в режиме только для чтения
#include <stdio.h>
#include <string.h>
#include <windows.h>
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);
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.