Funciones para manejo de memoria virtual

Ya hemos comentado que gracias al uso del modelo de memoria virtual, salvo para crear objetos de memoria descartables, con el API32 podremos usar las funciones estándar C, o los operadores de C++ para manejar memoria dinámicamente. Sin embargo, el modelo de memoria virtual nos permite un control sobre la memoria que no está disponible si sólo usamos funciones y operadores estándar.

El modelo virtual nos permite hacer cosas como:

Reservar direcciones de memoria virtual

Las funciones VirtualAlloc y VirtualAllocEx permiten reservar un rango de direcciones, sin asignarles memoria física, o asignándosela.

  • Podemos reservar direcciones de memoria, sin asignarles memoria física, de modo que se deje espacio para que estructuras dinámicas de datos crezcan durante la ejecución.
  • Asignar memoria a direcciones previamente reservadas.
  • Hacer ambas cosas a la vez.
   int *puntero;
   ...
   /* Reservar memoria sin asignar almacenamiento físico */
   puntero = VirtualAlloc(NULL, 100 * sizeof(int), MEM_RESERVE, PAGE_NOACCESS);
   /* Acomodar físicamente memoria previamente reservada */
   VirtualAlloc(puntero, 100*sizeof(int), MEM_COMMIT, PAGE_READWRITE);
   /* Reservar y acomodar espacio para memoria de una vez */
   puntero = VirtualAlloc(NULL, 100 * sizeof(int),
      MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

Liberar direcciones de memoria virtual

Las funciones VirtualFree y VirtualFreeEx permite realizar las operaciones inversas a las anteriores.

  • Liberar direcciones de memoria reservadas.
  • Liberar memoria asignada sin liberar las direcciones.
  • Liberar direcciones reservadas y memoria asignada.
   int *puntero;

   /* Libera memoria */
   VirtualFree(puntero, 0, MEM_RELEASE);
   /* Desasigna memoria, la memoria sigue reservada */
   VirtualFree(puntero, 100*sizeof(int), MEM_DECOMMIT);

Bloquear páginas de memoria asignada

La función VirtualLock permite bloquear determinadas páginas para que siempre permanezcan en memoria física, y no puedan ser transferidas al fichero de paginación.

Para desbloquear estas páginas se usa la función VirtualUnlock.

   int *puntero;

   ...
   VirtualLock(puntero, 100*sizeof(int));
   ...
   VirtualUnlock(puntero, 100*sizeof(int));

Establecer atributos de protección de acceso

Las funciones VirtualProtect y VirtualProtectEx permiten asignar atributos de lectura/escritura, sólo lectura o sin acceso.

   int *puntero;
   DWORD protant; /* Valor anterior de la protección */

   VirtualProtect(puntero, 100*sizeof(int), PAGE_READONLY, &protant);

Obtener información sobre páginas de memoria

Las funciones VirtualQuery y VirtualQueryEx se usan para obtener información sobre rangos de páginas de memoria virtual.

Estas funciones obtienen datos sobre rangos de páginas de memoria virtual a través de una estructura MEMORY_BASIC_INFORMATION. De este modo podemos saber el tamaño de un bloque de memoria, su estado, su tipo de protección, etc. Esta estructura también nos informa de esos mismos valores en la primera llamada a VirtualAlloc, independientemente del estado en que esté actualmente.

   int *puntero;
   MEMORY_BASIC_INFORMATION mbi;
 
   VirtualQuery(puntero, &mbi, sizeof(MEMORY_BASIC_INFORMATION));

Generalmente, en nuestras aplicaciones, no necesitaremos recurrir a funciones del API para manejar memoria, ya que el sistema se encarga de gestionar las llamadas a las funciones estándar de memoria: malloc, free, etc, y el uso de los operadores new y delete, de modo que en realidad siempre usaremos memoria virtual. El sistema se encarga también de proporcionar el almacenamiento físico para esa memoria, y nosotros no tendremos que preocuparnos por esos temas.

Pero a veces puede ser necesario gestionar la memoria de nuestra aplicación, asegurarse de que va a existir memoria disponible en fases siguientes del programa, aunque no la vayamos a necesitar de forma inmediata, proteger ciertas zonas, etc. En esos casos será útil saber que existen estos mecanismos, y saber aplicarlos de forma adecuada a cada caso.

Ejemplo 48


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 48 win048.zip 2005-08-14 4250 bytes 297