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