Extracto del libro: "Los Tomos de Delphi: Núcleo del API

Anuncio
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');
Descargar