Funciones de gestión de memoria n 445 Ejemplo Listado 9-14: Moviendo memoria de un array a otro var Form1: TForm1; Array1,Array2: array[0..400] of Integer; implementation procedure TForm1.Button1Click(Sender: TObject); var iLoop: Integer; begin {Mover la información de un array al otro} MoveMemory(@Array2, @Array1, SizeOf(Array1)); {Mostrar la información} for iLoop := 0 to 400 do begin StringGrid1.Cells[iLoop,0] := IntToStr(Array1[iLoop]); StringGrid2.Cells[iLoop,0] := IntToStr(Array2[iLoop]); end; end; procedure TForm1.FormCreate(Sender: TObject); var iLoop: Integer; begin {Inicializar los arrays} for iLoop := 0 to 400 do begin {Inicializar elementos de este array con el valor del contador} Array1[iLoop] := iLoop; StringGrid1.Cells[iLoop,0] := IntToStr(Array1[iLoop]); {Inicializar elementos de este array con ceros} Array2[iLoop] := 0; StringGrid2.Cells[iLoop,0] := IntToStr(Array2[iLoop]); end; end; VirtualAlloc Windows.Pas Sintaxis VirtualAlloc( lpvAddress: Pointer; dwSize: DWORD; flAllocationType: DWORD; flProtect: DWORD {puntero a región de memoria a reservar/comprometer} {tamaño de la región de memoria en bytes} {tipo de reserva} {tipo de protección de acceso} 9 446 Capítulo 9 n ): Pointer; {devuelve un puntero a la memoria reservada} Descripción VirtualAlloc se utiliza para reservar o comprometer una región de páginas en el espacio de direcciones virtual del proceso. La memoria comprometida por VirtualAlloc es inicializada a cero. La región será reservada o comprometida de acuerdo a las opciones que se establezcan en el parámetro flAllocationType. Para comprometer una región de memoria a almacenamiento físico utilizando la opción MEM_COMMIT, la aplicación deberá primero haberla reservado mediante la opción MEM_RESERVE. Esto puede hacerse en dos llamadas sucesivas a VirtualAlloc para la misma región de memoria. VirtualAlloc puede utilizarse para reservar un bloque grande de páginas, para luego comprometer en la medida de la necesidad trozos más pequeños del bloque reservado, lo que permite a la aplicación reservar memoria en su espacio de direcciones virtual sin consumir memoria física hasta que sea necesario. Parámetros lpvAddress: Puntero a la dirección de inicio de la región de memoria virtual a reservar. A este parámetro se le debe asignar el valor devuelto previamente por una llamada Figura 9-6: El estado de la memoria reservada. anterior a VirtualAlloc si la región de memoria virtual ha sido ya reservada y ahora se desea comprometer. El valor nil le permite a Windows determinar la dirección de inicio de la región, que debe ser el método más utilizado. Si la dirección es especificada, será redondeada por exceso a la siguiente frontera de página de 64 KB. dwSize: Especifica la cantidad de bytes a reservar o comprometer. La región de páginas que se reservará incluye todas las páginas que contienen uno o más bytes en el rango de memoria que va desde lpvAddress hasta lpvAddress + dwSize. Por lo tanto, un rango de memoria de dos bytes que cruce una frontera de página de 64 KB provocará que ambas Funciones de gestión de memoria n 447 páginas de 64 KB sean reservadas. Si el parámetro lpvAddress es nil, este valor es redondeado a la siguiente frontera de página de 64 KB. flAllocationType: Especifica el tipo de reserva a realizar. Este parámetro puede tomar uno o más de los valores de la Tabla 9-13. flProtect: Especifica el tipo de protección de acceso a aplicar a la memoria virtual reservada. Este parámetro puede tomar uno de los valores de la Tabla 9-14. Valor que devuelve Si la función tiene éxito, devuelve un puntero a la dirección base de la región de memoria reservada; en caso contrario devuelve nil. Para obtener información adicional sobre un error, utilice la función GetLastError. Véase además GlobalAlloc, HeapAlloc, VirtualFree, VirtualLock, VirtualProtect, VirtualQuery 9 Ejemplo Listado 9-15: Reservando memoria virtual procedure TForm1.Button1Click(Sender: TObject); type ArrayType = array[0..6000] of integer; var Arrayptr: ^ArrayType; // puntero a buffer iLoop: integer; // contador MemInfo: TMemoryBasicInformation; // registro de consulta OldProt: Integer; begin {Reservar memoria del espacio de direcciones virtual para nuestro array} Arrayptr := VirtualAlloc(nil, SizeOf(ArrayType), MEM_RESERVE or MEM_COMMIT, PAGE_READONLY); {Comprobar errores} if Arrayptr = nil then begin ShowMessage('Error allocating array'); Exit; end; {Examinar atributos de la memoria} VirtualQuery(Arrayptr, MemInfo, SizeOf(TMemoryBasicInformation)); {Mostrar información sobre la región de memoria} ListBox1.Items.Add('Base Address: ' + IntToHex(LongInt(MemInfo.BaseAddress),8)); ListBox1.Items.Add('Allocation Base: ' + IntToHex(LongInt( MemInfo.AllocationBase),8)); ListBox1.Items.Add('Region Size: ' + IntToStr(MemInfo.RegionSize) + ' bytes');