Если использовать VirtualAlloc описанным образом, эта функция выделит участок памяти указанного объема точно так же, как если бы вы использовали для этой цели стандартный вызов malloc. Зачем это может потребоваться? В отличие от malloc функция VirtualAlloc позволяет выделить участок памяти, выровненный по границе страницы, который будет обладать указанными вами атрибутами. Кроме того, в случае необходимости вы сможете корректно освободить этот участок памяти и передать его в ведение операционной системы. Дело в том, что некоторые библиотеки не возвращают освобождаемую память операционной системе.
Если вы хотите изменить уровень защиты для какой-либо одной (или всех) страницы выделенного участка, вы можете воспользоваться вызовом VirtualProtect. При этом участку памяти можно присвоить любой из атрибутов, перечисленных в табл.1. Функция VirtualProtectEx позволяет выполнить ту же процедуру в отношении памяти, которой обладает некоторый процесс. Конечно, в этом случае, программа, обращающаяся к VirtualProtectEx, должна обладать необходимыми привилегиями в отношении целевого процесса. Чтобы освободить память, выделенную при помощи VirtualAlloc, необходимо обратиться к функции VirtualFree.
Но помимо перечисленных функция Virtua1Alloc обладает некоторыми другими весьма полезными возможностями. Если в качестве третьего аргумента функции Virtua1Alloc вместо флага МЕМ_СОММIТ использовать флаг MEM_RESERVE, функция сработает иначе. В этом случае функция Virtua1Alloc резервирует указанный объем линейного адресного пространства, однако реальная физическая или виртуальная память при этом не выделяется. Речь идет лишь о резервировании диапазона адресов.
Когда вы захотите выделить реальную память, соответствующую этим адресам, вы должны обратиться к вызову Virtua1Alloc и передать ему адрес участка памяти и флаг МЕМ_СОММIТ. Выделять память сразу для всего зарезервированного диапазона адресов вовсе не обязательно. Например, можно зарезервировать 10 Мбайт адресного пространства, а затем выделять память из этого диапазона адресов фрагментами по 100 Кбайт.
VirtualAlloc на практике
Чтобы сравнить скорость выполнения функции Virtua1Alloc в различных режимах, запустите программу, исходный код которой приведен в листинге 1. Эта программа получает в индивидуальное пользование относительно большой участок памяти, при этом используются три разных метода. По умолчанию программа работает с блоком памяти объемом 75 Мбайт. Это значение приемлемо для тестирования механизмов выделения/освобождения памяти. Если вы захотите работать с блоком памяти другого размера, его размер (количество мегабайт) можно указать в командной строке при запуске программы.
Листинг 1.
#include <windows.h>
#include <iostream.h>
char *p=NULL;
#define MEGABYTE 1048576
#define MSIZE 75
void main(int argc, char *argv[])
{
char choice;
int msize=0;
if (argc>1) msize=atoi(argv[1]);
if (!msize) msize=MSIZE;
do
{
int valid=1;
if (p)
{
cout<<"\nОсвобождение памяти\n";
VirtualFree(p,0,MEM_RELEASE);
p=NULL;
cout<<"Завершено\n";
}
cout<<"1 - Выделить " <<msize<< "MB памяти\n";
cout<<"2 - Зарезервировать " <<msize<<"MB памяти\n";
cout<<"3 - Зарезервировать " <<msize<<"MB памяти и выделить в ней 1MB\n";
cout<<"4 - Выход\n";
cout<<"Ваш выбор: ";
cin>>choice;
switch (choice)
{
case '1':
cout<<"\nВыделение памяти\n";
p=(char *)VirtualAlloc(NULL, msize*MEGABYTE,
MEM_COMMIT,PAGE_READWRITE);
break;
case '2':
cout<<"\nРезервирование памяти\n";
p=(char *)VirtualAlloc(NULL, msize*MEGABYTE,
MEM_RESERVE, PAGE_READWRITE);
break;
case '3':
cout<<"\nРезервирование и частичное выделение памяти\n";
p=(char *)VirtualAlloc(NULL, msize*MEGABYTE,
MEM_RESERVE, PAGE_READWRITE);
cout<<"\nВыделение\n";
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.