Функция VirtualAlloc резервирует или предоставляет физическую память под указанными страницами в виртуальном адресном пространстве процесса. Память, выделяемая этой функцией, автоматически инициализируется нулями, кроме случая, когда указан флаг MEM_RESET.
Для того, чтобы выделить память в виртуальном адрусном пространстве другого процесса следует использовать функцию VirtualAllocEx.
function VirtualAlloc( lpvAddress: Pointer; // начальный адрес региона для резервирования/передачи памяти dwSize: DWORD; // размер региона flAllocationType: DWORD; // способ выделения flProtect: DWORD // атрибуты доступа ): Pointer; stdcall;
Параметры
lpvAddress [in]
Указывает желаемый базовый адрес региона памяти, для которого будет произведено
выделение памяти. Если указанная память резервируется, то этот адрес будет
округлен вниз до границы 64 Кб. Если память уже зарезервирована и происходит
передача памяти, указанный адрс округляется вниз до ближайшей границы страницы.
Для того, чтобы определить размер страницы на компьютере, на котором выполняется
приложение, необходимо использовать функцию GetSystemInfo. Если желаетый адрес
равен nil, то система сама определит место, где будет выделен регион
памяти.
dwSize [in]
Указывает размер в байтах запрашиваемого региона памяти. Если указанный желаемый
адрес lpvAddress равен nil, то указанное значение округлится вверх таким
образом, чтобы включать целое число страниц. В противном случае выделяемые
страницы озватят весь диапазон начинающийся по адресу lpvAddress и
заканчивающийся по адресу lpvAddress + dsSize. В этом случае возможно выделение
двух страниц, память на которых будет использована не полностью (в начале и в
конце).
flAllocationType [in]
Указывает способ выделения памяти. Указанный параметр может быть комбинацией
следующих значений:
| Флаг | Назначение |
|---|---|
| MEM_COMMIT |
Передает память указанному региону адресного пространства. Память может находиться как непосредственно в оперативной памяти, так и в файле подкачки. Попытка передать памяти диапазону адресов,для которых уже выделена память, не может привести к ошибке. Это значит, что вы можете спокойно получать физическую память под адреса, находящеся в зарезервированном адресном пространстве, не тревожась ни за то, что возникнет ошибка в случае пересекаются указанного диапазона со страницами, которые уже имеют под собой физическую память, ни за то, что содержимое ранее выделенных страниц обнулиться. |
| MEM_PHYSICAL |
Выделяет физическую память. Это значение предназначено исключительно для работы с расширением адресной облочки Windows. |
| MEM_RESERVE |
Резервирование указанного диапазона виртуального адресного пространства процесса без передачи физической памяти. Зарезервированный фрагменты памяти не могут участвовать в дальнейших операциях выделения памяти (например при помощи функций GetMem или LocalAlloc или подобных им) до тех пор пока она не будет освобождена. Физическая память под зарезервированные страницы может быть выделена только при помощи вызова функции VirtualAlloc. |
| MEM_RESET |
Windows NT/2000. Указывает, что диапазон адресов начиная с lpvAddress и длины dwSize больше для нас не представляет интереса. При обращении к таким блокам (чтение/запись) соответсвующие страницы не будут загружаться из файла подкачки. Тем не менее физическая память под указанным диапазоном остается, и указанный фрагмент можно будет использоваться в дальнейшем. Важно! Установка этого флага не гарантирует, что указанный диапазон будет обнулен. Если вы хотите обнулить оюду или несколько страниц, необходимо снять физическау память с них и передать ее им снова. Если вы указываете значение MEM_RESET, функция VirtualAlloc игнорирует значение параметра flProtect. Тем не менее необходимо передать в этом параметре правильное значение, например PAGE_NOACCESS. Функция VirtualAlloc закончиться неуспешно при попытке использования флага MEM_RESET к диапазону адресов, занятого файлом проецируемым в память. Доступный для всех просмотр файла проецируемого в память не исказиться и будет, при необходимости, записан в файл подкачки. |
| MEM_TOP_DOWN |
Windows NT/2000. Выделяет память по наиболее высокому возможному адресу. |
| MEM_WRITE_WATCH |
Windows 98. Указывает системе на то, что необходимо производить слежение за попытком модификации всемх страниц памяти, которые принадлежат указанному диапазону. Если вы используете этот флаг, вы должны также указать флаг MEM_RESERVE. Слежение за записью в указанные страницы будет возможным до тех пор, пока указанный регион памяти не будет освобожден. Для того, чтобы получить список страниц, которые были модифицированы, или для того, чтобы сбросить состояние слежения, необходимо возпользоваться функцией GetWriteWatch. Для того, чтобы только сбросить состояние слежение, необходимо произвести вызов ResetWriteWatch. |
flProtect [in]
Указывает тип доступа к памяти. Если указанный диапазон страниц имеет под собой
физическую память, вы можете указать одно из следующих значений, по
необходимости скомбинированных с флагами PAGE_GUARD и PAGE_NOCACHE.
| Флаг | Назначение |
|---|---|
| PAGE_READONLY |
Устанавливает права чтения для указанного региона. Попытка записи в этот регион приведет к нарушению доступа. Если операционная система выполняет различие между правами только для чтения и выполнения кода, то попытка передать управление на один из адресов, принадлежащих указанному региону, также вызовет нарушение доступа. |
| PAGE_READWRITE |
Предоставляет права чтения/записи для указанного региона. |
| PAGE_EXECUTE |
Предоставляет права выполнения кода для указанного региона. Попытка чтения/записи страниц указанного региона приведет к нарушению доступа. |
| PAGE_EXECUTE_READ |
Предоставляет права чтения памяти и выполнения кода для указанного региона. Попытка записи в страницы указанного региона приведет к нарушению доступа. |
| PAGE_EXECUTE_READWRITE |
Предоставляет права чтения/записи памяти и выполнения кода для указанного региона. |
| PAGE_GUARD |
Windows NT/2000. Делает страницы памяти в указанном регионе защищаемыми. Любая попытка чтения или записи в такие страницы вызовет исключение STATUS_GUARD_PAGE, и одновременно приведет к выключению статуса защищаемости. Таким образом защита страниц может быть отличным способом сигнализации доступа к страницам памяти. Флаг PAGE_GUARD является модификатором типа защиты страниц. Приложение может использовать этот флаг только в том случае, если обращение к странице происходит без возникновения исключительной ситуации. Указанный флаг нельзя использовать совместно со правами доступа PAGE_NOACCESS. Любая попытка доступа к памяти приводит к тому, что система снимает защиту страницы, оставляя при этом все остальные права доступа к странице. Если исключение защиты страницы случилось в сервисе, то обычно сервис индицирует появление ошибки. Windows 95/98. Для симуляции подобного поведения необходимо использовать атрибут защиты страницы PAGE_NOACCESS. |
| PAGE_NOACCESS |
Запрещает любой доступ к странице, которая имеет под собой физическую память. Любая попытка чтения/записи или передачи управления на указанную страницу приводит к исключению нарушения доступа вызываемого общей ошибкой защиты. |
| PAGE_NOCACHE |
Запрещает любое кэширование указанного диапазона страниц. Это аппаратный атрибут физической памяти может быть рассмотрен как "нет кэшированию". Этот атрибут не рекомендуется для обычного использования. Этот атрибут необходим для драйверов устройств, например для проекции кадров видеобуфера без кэширования. Этот атрибут используется только в том случае, когда указан атрибут доступа к странице отличный от PAGE_NOACCESS. |
Возвращаемое значение
В случае удачного завершения возвращаемым значением является базовый адрес выделенных страниц памяти.
К случае ошибк функция возвращает nil. Для получения расширенной информации об ошибке следует сделать вызов GetLastError.
Описание
Функция VirtualAlloc способна выполнить следующие операции:
Вы можете использовать функцию VirtualAlloc для того, чтобы зерезервировать некоторый фрагмент памяти, а впоследсвии использовать эту же функцию для того, чтобы передавать физическую память выборочным страницам зарезервированного блока. Это позволяет процессу резервировать регион своего виртуального адресного пространства без выделения непосредственно физической памяти, если это необходимо.
Каждая страницы виртуальной памяти может находиться в одном из следующих состояний:
| Состояние страницы | Описание |
|---|---|
Свободная |
Под такой страницей нет физической памяти, она не является зарезервированной и недоступна процессу. Функция VirtualAlloc может либо зарезервировать такую страницу, либо одновременно как зарезервировать, так и передать такой странице физическую память. |
| Зарезервированная |
Диапазон адресов, занимаемый страницей, не может быть получен в результате выполнения какой-либо функции, выделяющей память. Но доступ к такой странице невозможен и она не занимает места в памяти. Функция VirtualAlloc может выделить физическую память такой странице, но не может повторно ее зарезервировать. Функция VirtualFree позволяет снять резервирование страницы, после чего страница станет свободной. |
| Переданная процессу |
Для такой страницы выделено место в памяти (либо в оперативной, либо в файле подкачки). Доступ к странице контролируется атрибутами защиты страницы. Выделение памяти под страницу и ее инициализация выполняется операционной системой только при попытке осуществления чтения/запии содержимого вновь выделенной страницы. По завершении процесса системой освобождаются все страницы, принадлежащие данному процессу. Функция VirtualAlloc может передать физическую память страницам, которые уже имеют ее под собой. Это делает возможным передачу физической памяти диапазону страниц, не обращая внимания на то, проиводилась ли передача физической памяти под эти страницы ранее. Функция VirtualFree позволяет либо освободить физическую память, находящуюся под страницей, либо как освободить физическую память, так и снять резервирование со страницы. |
Если параметр lpvAddress не равен nil, функция использует значение параметров lpAddress и dwSize для того, чтобы вычислить размер выделяемого региона памяти. Текущее состояние страницы полученном регионе должно быть совместимо с тем способом выделения, что указан в параметре flAllocationType. В противном случае памяти не выделяется и функция возвратит ошибку. Требования по совместимости состояния страниц со способом выделения приведены в предшествующей таблице.
Windows NT/2000: Указание атрибута PAGE_GUARD доступа к странице позволяет создавать в памяти защищаемые страницы. Создание таких страниц позволяет нам отловить попытки доступа к странице. Для большей информации смотрите раздел "Создание защищаемых страниц".
Расширение адресной оболочки Windows (AWE):
Функция VirtualAlloc может быть использована для того, чтобы выделить AWE-регион памяти в виртуальном адресном пространстве вызывающего процесса. Этот регион памяти может быть в дальнейшем использован для проецирования на него физических страниц памяти.
В этом случае в параментре flAllocationType должна быть указана комбинция флагов MEM_PHYSICAL и MEM_RESERVE, а флаг MEM_COMMIT не указывается. Значение атрибута доступа к странице flProtect должно быть равным PAGE_READWRITE.
Функция VirtualFree может быть использована для того, чтобы освободит AWE-регион памяти, в этом случае происходит разпроецирование всех страниц физической памяти, ранее спроецированных в указанный регион. Тем не менее сами страницы физической памяти не освобождаются и приложение может их использовать в дальнейшем. Для освобождения самих страниц физической памяти приложение должно использовать вызов FreeUserPhysicalPages. По завершении процесса все выделенные ним ресурсы автоматически очистятся.
Требования
Windows NT/2000: Требуется Windows NT 3.1 или более поздняя версия
Windows 95/98: Требуется Windows 95 или более поздняя версия
Бибиотека: Kernel32.dll
Подключаемый модуль: Windows
Смотри также:
ResetWriteWatch |
VirtualAllocEx![]() |
© Mystic, 2002