Función VirtualAlloc (memoryapi.h)

Reserva, confirma o cambia el estado de una región de páginas en el espacio de direcciones virtuales del proceso de llamada. La memoria asignada por esta función se inicializa automáticamente en cero.

Para asignar memoria en el espacio de direcciones de otro proceso, use la función VirtualAllocEx .

Sintaxis

LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

Parámetros

[in, optional] lpAddress

Dirección inicial de la región que se va a asignar. Si se reserva la memoria, la dirección especificada se redondea hacia abajo hasta el múltiplo más cercano de la granularidad de asignación. Si la memoria ya está reservada y se confirma, la dirección se redondea hacia abajo hasta el límite de la página siguiente. Para determinar el tamaño de una página y la granularidad de asignación en el equipo host, use la función GetSystemInfo . Si este parámetro es NULL, el sistema determina dónde asignar la región.

Si esta dirección está dentro de un enclave que no se ha inicializado llamando a InitializeEnclave, VirtualAlloc asigna una página de ceros para el enclave en esa dirección. La página debe no confirmarse previamente y no se medirá con la instrucción EEXTEND del modelo de programación intel Software Guard Extensions.

Si la dirección se encuentra dentro de un enclave que inicializó, se produce un error en la operación de asignación con el error ERROR_INVALID_ADDRESS . Esto es cierto para enclaves que no admiten la administración de memoria dinámica (es decir, SGX1). Los enclaves SGX2 permitirán la asignación y el enclave debe aceptar la página después de que se haya asignado.

[in] dwSize

Tamaño de la región, en bytes. Si el parámetro lpAddress es NULL, este valor se redondea al límite de la página siguiente. De lo contrario, las páginas asignadas incluyen todas las páginas que contienen uno o varios bytes en el intervalo de lpAddress a lpAddress+dwSize. Esto significa que un intervalo de 2 bytes estratega un límite de página hace que ambas páginas se incluyan en la región asignada.

[in] flAllocationType

Tipo de asignación de memoria. Este parámetro debe contener uno de los valores siguientes.

Valor Significado
MEM_COMMIT
0x00001000
Asigna cargos de memoria (del tamaño total de la memoria y los archivos de paginación en el disco) para las páginas de memoria reservadas especificadas. La función también garantiza que, cuando el autor de la llamada accede inicialmente a la memoria, el contenido será cero. Las páginas físicas reales no se asignan a menos que se tenga acceso a las direcciones virtuales.

Para reservar y confirmar páginas en un paso, llame a VirtualAlloc con MEM_COMMIT | MEM_RESERVE.

Al intentar confirmar un intervalo de direcciones específico, se especifica MEM_COMMIT sin MEM_RESERVE y se produce un error en un lpAddress que no sea NULL, a menos que ya se haya reservado todo el intervalo. El código de error resultante es ERROR_INVALID_ADDRESS.

Un intento de confirmar una página que ya está confirmada no hace que se produzca un error en la función. Esto significa que puede confirmar páginas sin determinar primero el estado de compromiso actual de cada página.

Si lpAddress especifica una dirección dentro de un enclave, flAllocationType debe ser MEM_COMMIT.

MEM_RESERVE
0x00002000
Reserva un intervalo del espacio de direcciones virtuales del proceso sin asignar ningún almacenamiento físico real en memoria o en el archivo de paginación en el disco.

Puede confirmar páginas reservadas en llamadas posteriores a la función VirtualAlloc . Para reservar y confirmar páginas en un paso, llame a VirtualAlloc con MEM_COMMIT MEM_RESERVE | .

Otras funciones de asignación de memoria, como malloc y LocalAlloc, no pueden usar un intervalo reservado de memoria hasta que se libere.

MEM_RESET
0x00080000
Indica que los datos del intervalo de memoria especificados por lpAddress y dwSize ya no son de interés. Las páginas no deben leerse ni escribirse en el archivo de paginación. Sin embargo, el bloque de memoria se usará de nuevo más tarde, por lo que no debe descommitido. Este valor no se puede usar con ningún otro valor.

El uso de este valor no garantiza que el intervalo operado con MEM_RESET contenga ceros. Si desea que el intervalo contenga ceros, descommita la memoria y, a continuación, vuelva a enviarla.

Al especificar MEM_RESET, la función VirtualAlloc omite el valor de flProtect. Sin embargo, debe establecer flProtect en un valor de protección válido, como PAGE_NOACCESS.

VirtualAlloc devuelve un error si usa MEM_RESET y el intervalo de memoria se asigna a un archivo. Una vista compartida solo es aceptable si se asigna a un archivo de paginación.

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO solo se debe llamar a en un intervalo de direcciones al que MEM_RESET se aplicó correctamente anteriormente. Indica que los datos del intervalo de memoria especificado por lpAddress y dwSize son de interés para el autor de la llamada e intenta invertir los efectos de MEM_RESET. Si la función se ejecuta correctamente, significa que todos los datos del intervalo de direcciones especificados están intactos. Si se produce un error en la función, al menos algunos de los datos del intervalo de direcciones se han reemplazado por ceros.

Este valor no se puede usar con ningún otro valor. Si se llama a MEM_RESET_UNDO en un intervalo de direcciones que no se MEM_RESET anteriormente, el comportamiento no está definido. Al especificar MEM_RESET, la función VirtualAlloc omite el valor de flProtect. Sin embargo, debe establecer flProtect en un valor de protección válido, como PAGE_NOACCESS.

Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 y Windows XP: La marca de MEM_RESET_UNDO no se admite hasta Windows 8 y Windows Server 2012.

Este parámetro también puede especificar los valores siguientes como se indica.

Valor Significado
MEM_LARGE_PAGES
0x20000000
Asigna memoria con compatibilidad con páginas grandes.

El tamaño y la alineación deben ser un múltiplo del mínimo de página grande. Para obtener este valor, use la función GetLargePageMinimum .

Si especifica este valor, también debe especificar MEM_RESERVE y MEM_COMMIT.

MEM_PHYSICAL
0x00400000
Reserva un intervalo de direcciones que se puede usar para asignar páginas de extensiones de ventanas de direcciones (AWE).

Este valor se debe usar con MEM_RESERVE y ningún otro valor.

MEM_TOP_DOWN
0x00100000
Asigna memoria en la dirección más alta posible. Esto puede ser más lento que las asignaciones normales, especialmente cuando hay muchas asignaciones.
MEM_WRITE_WATCH
0x00200000
Hace que el sistema realice un seguimiento de las páginas escritas en en la región asignada. Si especifica este valor, también debe especificar MEM_RESERVE.

Para recuperar las direcciones de las páginas en las que se ha escrito desde que se asignó la región o se restableció el estado de seguimiento de escritura, llame a la función GetWriteWatch . Para restablecer el estado de seguimiento de escritura, llame a GetWriteWatch o ResetWriteWatch. La característica de seguimiento de escritura permanece habilitada para la región de memoria hasta que se libera la región.

[in] flProtect

Protección de memoria para la región de páginas que se va a asignar. Si se confirman las páginas, puede especificar cualquiera de las constantes de protección de memoria.

Si lpAddress especifica una dirección dentro de un enclave, flProtect no puede ser ninguno de los valores siguientes:

  • PAGE_NOACCESS
  • PAGE_GUARD
  • PAGE_NOCACHE
  • PAGE_WRITECOMBINE

Al asignar memoria dinámica para un enclave, el parámetro flProtect debe ser PAGE_READWRITE o PAGE_EXECUTE_READWRITE.

Valor devuelto

Si la función se ejecuta correctamente, el valor devuelto es la dirección base de la región asignada de páginas.

Si la función no se realiza correctamente, el valor devuelto es NULL. Para obtener información de error extendida, llame a GetLastError.

Comentarios

Cada página tiene un estado de página asociado. La función VirtualAlloc puede realizar las siguientes operaciones:

  • Confirmar una región de páginas reservadas
  • Reservar una región de páginas gratuitas
  • Reservar y confirmar simultáneamente una región de páginas gratuitas

VirtualAlloc no puede reservar una página reservada. Puede confirmar una página que ya está confirmada. Esto significa que puede confirmar un intervalo de páginas, independientemente de si ya se han confirmado y la función no producirá un error.

Puede usar VirtualAlloc para reservar un bloque de páginas y, a continuación, realizar llamadas adicionales a VirtualAlloc para confirmar páginas individuales desde el bloque reservado. Esto permite que un proceso reserve un intervalo de su espacio de direcciones virtuales sin consumir almacenamiento físico hasta que sea necesario.

Si el parámetro lpAddress no es NULL, la función usa los parámetros lpAddress y dwSize para calcular la región de las páginas que se van a asignar. El estado actual de todo el intervalo de páginas debe ser compatible con el tipo de asignación especificado por el parámetro flAllocationType . De lo contrario, se produce un error en la función y no se asigna ninguna de las páginas. Este requisito de compatibilidad no impide confirmar una página ya confirmada, como se mencionó anteriormente.

Para ejecutar código generado dinámicamente, use VirtualAlloc para asignar memoria y la función VirtualProtect para conceder acceso PAGE_EXECUTE .

La función VirtualAlloc se puede usar para reservar una región de extensiones de ventana de direcciones (AWE) de memoria dentro del espacio de direcciones virtuales de un proceso especificado. A continuación, esta región de memoria se puede usar para asignar páginas físicas hacia y fuera de la memoria virtual según lo requiera la aplicación. Los valores MEM_PHYSICAL y MEM_RESERVE deben establecerse en el parámetro AllocationType . No se debe establecer el valor de MEM_COMMIT . La protección de páginas debe establecerse en PAGE_READWRITE.

La función VirtualFree puede descommitir una página confirmada, liberar el almacenamiento de la página, o puede descommitir y liberar simultáneamente una página confirmada. También puede liberar una página reservada, por lo que es una página gratuita.

Al crear una región que será ejecutable, el programa de llamada asume la responsabilidad de garantizar la coherencia de caché a través de una llamada adecuada a FlushInstructionCache una vez que se haya establecido el código. De lo contrario, los intentos de ejecutar código fuera de la región recién ejecutable pueden producir resultados imprevisibles.

Ejemplos

Para obtener un ejemplo, consulte Reservación y confirmación de memoria.

Requisitos

   
Cliente mínimo compatible Windows XP [aplicaciones de escritorio | aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado memoryapi.h (incluya Windows.h, Memoryapi.h)
Library onecore.lib
Archivo DLL Kernel32.dll

Consulte también

Funciones de administración de memoria

Funciones de memoria virtual

VirtualAllocEx

VirtualFree

VirtualLock

VirtualProtect

VirtualQuery

API de Vertdll disponibles en enclaves de VBS