Pascal - Gestión de la memoria
Este capítulo explica la administración de memoria dinámica en Pascal. El lenguaje de programación Pascal proporciona varias funciones para la asignación y administración de memoria.
Asignar memoria dinámicamente
Mientras programa, si conoce el tamaño de una matriz, entonces es fácil y puede definirla como una matriz. Por ejemplo, para almacenar el nombre de cualquier persona, puede tener un máximo de 100 caracteres para que pueda definir algo de la siguiente manera:
var
name: array[1..100] of char;
Pero ahora, consideremos una situación en la que no tiene idea de la longitud del texto que necesita almacenar, por ejemplo, desea almacenar una descripción detallada sobre un tema. Aquí, necesitamos definir un puntero a cadena sin definir cuánta memoria se requiere.
Pascal proporciona un procedimiento newpara crear variables de puntero.
program exMemory;
var
name: array[1..100] of char;
description: ^string;
begin
name:= 'Zara Ali';
new(description);
if not assigned(description) then
writeln(' Error - unable to allocate required memory')
else
description^ := 'Zara ali a DPS student in class 10th';
writeln('Name = ', name );
writeln('Description: ', description^ );
end.
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Name = Zara Ali
Description: Zara ali a DPS student in class 10th
Ahora, si necesita definir un puntero con un número específico de bytes para ser referido por él más tarde, debe usar el getmem función o la getmem procedimiento, que tiene la siguiente sintaxis:
procedure Getmem(
out p: pointer;
Size: PtrUInt
);
function GetMem(
size: PtrUInt
):pointer;
En el ejemplo anterior, declaramos un puntero a una cadena. Una cadena tiene un valor máximo de 255 bytes. Si realmente no necesita tanto espacio, o un espacio más grande, en términos de bytes, el subprograma getmem permite especificar eso. Reescribamos el ejemplo anterior, usando getmem -
program exMemory;
var
name: array[1..100] of char;
description: ^string;
begin
name:= 'Zara Ali';
description := getmem(200);
if not assigned(description) then
writeln(' Error - unable to allocate required memory')
else
description^ := 'Zara ali a DPS student in class 10th';
writeln('Name = ', name );
writeln('Description: ', description^ );
freemem(description);
end.
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Name = Zara Ali
Description: Zara ali a DPS student in class 10th
Por lo tanto, tiene un control completo y puede pasar cualquier valor de tamaño mientras asigna memoria, a diferencia de las matrices, donde una vez definido el tamaño no se puede cambiar.
Cambiar el tamaño y liberar la memoria
Cuando sale su programa, el sistema operativo libera automáticamente toda la memoria asignada por su programa, pero como una buena práctica cuando ya no necesita memoria, debe liberar esa memoria.
Pascal proporciona el procedimiento dispose para liberar una variable creada dinámicamente mediante el procedimiento new. Si ha asignado memoria utilizando el getmem subprograma, entonces necesitas usar el subprograma freemempara liberar este recuerdo. Los subprogramas freemem tienen la siguiente sintaxis:
procedure Freemem(
p: pointer;
Size: PtrUInt
);
function Freemem(
p: pointer
):PtrUInt;
Alternativamente, puede aumentar o disminuir el tamaño de un bloque de memoria asignado llamando a la función ReAllocMem . Revisemos el programa anterior una vez más y hagamos uso de los subprogramas ReAllocMem y freemem . A continuación se muestra la sintaxis de ReAllocMem :
function ReAllocMem(
var p: pointer;
Size: PtrUInt
):pointer;
A continuación se muestra un ejemplo que utiliza los subprogramas ReAllocMem y freemem :
program exMemory;
var
name: array[1..100] of char;
description: ^string;
desp: string;
begin
name:= 'Zara Ali';
desp := 'Zara ali a DPS student.';
description := getmem(30);
if not assigned(description) then
writeln('Error - unable to allocate required memory')
else
description^ := desp;
(* Suppose you want to store bigger description *)
description := reallocmem(description, 100);
desp := desp + ' She is in class 10th.';
description^:= desp;
writeln('Name = ', name );
writeln('Description: ', description^ );
freemem(description);
end.
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Name = Zara Ali
Description: Zara ali a DPS student. She is in class 10th
Funciones de gestión de memoria
Pascal proporciona un cúmulo de funciones de gestión de memoria que se utilizan para implementar varias estructuras de datos e implementar programación de bajo nivel en Pascal. Muchas de estas funciones dependen de la implementación. Free Pascal proporciona las siguientes funciones y procedimientos para la gestión de la memoria:
SN | Nombre y descripción de la función |
---|---|
1 | function Addr(X: TAnytype):Pointer; Devuelve la dirección de la variable |
2 | function Assigned(P: Pointer):Boolean; Comprueba si un puntero es válido |
3 | function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt; Compara 2 bytes de búfer de memoria por byte |
4 | function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt; Compara 2 bytes de búfer de memoria por byte |
5 | function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt; Compara 2 bytes de búfer de memoria por byte |
6 | function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt; Compara 2 bytes de búfer de memoria por byte |
7 | function Cseg: Word; Devuelve segmento de código |
8 | procedure Dispose(P: Pointer); Libera memoria asignada dinámicamente |
9 | procedure Dispose(P: TypedPointer; Des: TProcedure); Libera memoria asignada dinámicamente |
10 | function Dseg: Word; Devuelve segmento de datos |
11 | procedure FillByte(var x; count: SizeInt; value: Byte); Llena la región de la memoria con un patrón de 8 bits |
12 | procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char); Llena la región de la memoria con cierto carácter |
13 | procedure FillDWord( var x; count: SizeInt; value: DWord); Llena la región de la memoria con un patrón de 32 bits |
14 | procedure FillQWord( var x; count: SizeInt; value: QWord); Llena la región de la memoria con un patrón de 64 bits |
15 | procedure FillWord( var x; count: SizeInt; Value: Word); Llena la región de la memoria con un patrón de 16 bits |
dieciséis | procedure Freemem( p: pointer; Size: PtrUInt); Libera memoria asignada |
17 | procedure Freemem( p: pointer ); Libera memoria asignada |
18 | procedure Getmem( out p: pointer; Size: PtrUInt); Asigna nueva memoria |
19 | procedure Getmem( out p: pointer); Asigna nueva memoria |
20 | procedure GetMemoryManager( var MemMgr: TMemoryManager); Devuelve el administrador de memoria actual |
21 | function High( Arg: TypeOrVariable):TOrdinal; Devuelve el índice más alto de matriz abierta o enumerada |
22 | function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt; Encuentra un valor del tamaño de un byte en un rango de memoria |
23 | function IndexChar( const buf; len: SizeInt; b: Char):SizeInt; Encuentra el valor del tamaño de un carácter en un rango de memoria |
24 | function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt; Encuentra un valor del tamaño de DWord (32 bits) en un rango de memoria |
25 | function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt; Encuentra un valor del tamaño de QWord en un rango de memoria |
26 | function Indexword( const buf; len: SizeInt; b: Word):SizeInt; Encuentra un valor del tamaño de una palabra en un rango de memoria |
27 | function IsMemoryManagerSet: Boolean; ¿Está configurado el administrador de memoria? |
28 | function Low( Arg: TypeOrVariable ):TOrdinal; Devuelve el índice más bajo de matriz abierta o enumerado |
29 | procedure Move( const source; var dest; count: SizeInt ); Mueve datos de una ubicación en la memoria a otra |
30 | procedure MoveChar0( const buf1; var buf2; len: SizeInt); Mueve datos hasta el primer carácter cero |
31 | procedure New( var P: Pointer); Asignar memoria dinámicamente para la variable |
32 | procedure New( var P: Pointer; Cons: TProcedure); Asigna memoria dinámicamente para variables |
33 | function Ofs( var X ):LongInt; Devuelve el desplazamiento de la variable |
34 | function ptr( sel: LongInt; off: LongInt):farpointer; Combina segmento y desplazamiento al puntero |
35 | function ReAllocMem( var p: pointer; Size: PtrUInt):pointer; Cambia el tamaño de un bloque de memoria en el montón |
36 | function Seg( var X):LongInt; Segmento de devoluciones |
37 | procedure SetMemoryManager( const MemMgr: TMemoryManager ); Configura un administrador de memoria |
38 | function Sptr: Pointer; Devuelve el puntero de pila actual |
39 | function Sseg: Word; Devuelve el valor del registro del segmento de la pila |