Pascal - Gerenciamento de Memória

Este capítulo explica o gerenciamento dinâmico de memória em Pascal. A linguagem de programação Pascal fornece várias funções para alocação e gerenciamento de memória.

Alocando memória dinamicamente

Ao fazer a programação, se você estiver ciente do tamanho de um array, então é fácil e você pode defini-lo como um array. Por exemplo, para armazenar o nome de qualquer pessoa, ele pode ter no máximo 100 caracteres, então você pode definir algo da seguinte maneira -

var
name: array[1..100] of char;

Mas agora, vamos considerar uma situação em que você não tem ideia sobre a extensão do texto que precisa armazenar, por exemplo, você deseja armazenar uma descrição detalhada sobre um tópico. Aqui, precisamos definir um ponteiro para string sem definir quanta memória é necessária.

Pascal fornece um procedimento newpara criar variáveis ​​de ponteiro.

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.

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

Agora, se você precisa definir um ponteiro com um número específico de bytes a serem referidos posteriormente, você deve usar o getmem função ou o getmem procedimento, que tem a seguinte sintaxe -

procedure Getmem(
   out p: pointer;
   Size: PtrUInt
);

function GetMem(
   size: PtrUInt
):pointer;

No exemplo anterior, declaramos um ponteiro para uma string. Uma string tem um valor máximo de 255 bytes. Se você realmente não precisa de tanto espaço, ou de um espaço maior, em termos de bytes, o subprograma getmem permite especificar isso. Vamos reescrever o exemplo 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.

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

Portanto, você tem controle total e pode passar qualquer valor de tamanho enquanto aloca memória, ao contrário dos arrays, onde uma vez definido o tamanho não pode ser alterado.

Redimensionar e liberar memória

Quando seu programa é lançado, o sistema operacional libera automaticamente toda a memória alocada por seu programa, mas como uma boa prática, quando você não precisar mais de memória, você deve liberar essa memória.

Pascal fornece o procedimento dispose para liberar uma variável criada dinamicamente usando o procedimento new. Se você alocou memória usando o getmem subprograma, então você precisa usar o subprograma freemempara liberar essa memória. Os subprogramas freemem têm a seguinte sintaxe -

procedure Freemem(
   p: pointer;
  Size: PtrUInt
);

function Freemem(
   p: pointer
):PtrUInt;

Como alternativa, você pode aumentar ou diminuir o tamanho de um bloco de memória alocado chamando a função ReAllocMem . Vamos verificar o programa acima, mais uma vez e fazer uso de ReAllocMem e FreeMem subprogramas. A seguir está a sintaxe para ReAllocMem -

function ReAllocMem(
   var p: pointer;
   Size: PtrUInt
):pointer;

A seguir é um exemplo que faz uso de ReAllocMem e FreeMem subprogramas -

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.

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Name = Zara Ali
Description: Zara ali a DPS student. She is in class 10th

Funções de gerenciamento de memória

Pascal fornece um conjunto de funções de gerenciamento de memória que é usado na implementação de várias estruturas de dados e implementação de programação de baixo nível em Pascal. Muitas dessas funções dependem da implementação. Free Pascal fornece as seguintes funções e procedimentos para gerenciamento de memória -

SN Nome e descrição da função
1

function Addr(X: TAnytype):Pointer;

Retorna o endereço da variável

2

function Assigned(P: Pointer):Boolean;

Verifica se um ponteiro é válido

3

function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt;

Compara 2 buffers de memória byte por byte

4

function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt;

Compara 2 buffers de memória byte por byte

5

function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt;

Compara 2 buffers de memória byte por byte

6

function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt;

Compara 2 buffers de memória byte por byte

7

function Cseg: Word;

Retorna o segmento de código

8

procedure Dispose(P: Pointer);

Libera memória alocada dinamicamente

9

procedure Dispose(P: TypedPointer; Des: TProcedure);

Libera memória alocada dinamicamente

10

function Dseg: Word;

Retorna segmento de dados

11

procedure FillByte(var x; count: SizeInt; value: Byte);

Preenche a região da memória com padrão de 8 bits

12

procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char);

Preenche a região da memória com determinado personagem

13

procedure FillDWord( var x; count: SizeInt; value: DWord);

Preenche a região da memória com padrão de 32 bits

14

procedure FillQWord( var x; count: SizeInt; value: QWord);

Preenche a região da memória com padrão de 64 bits

15 procedure FillWord( var x; count: SizeInt; Value: Word);

Preenche a região da memória com padrão de 16 bits

16

procedure Freemem( p: pointer; Size: PtrUInt);

Libera memória alocada

17

procedure Freemem( p: pointer );

Libera memória alocada

18

procedure Getmem( out p: pointer; Size: PtrUInt);

Aloca nova memória

19

procedure Getmem( out p: pointer);

Aloca nova memória

20

procedure GetMemoryManager( var MemMgr: TMemoryManager);

Retorna o gerenciador de memória atual

21

function High( Arg: TypeOrVariable):TOrdinal;

Retorna o índice mais alto de matriz aberta ou enumerada

22

function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt;

Encontra o valor do tamanho do byte em um intervalo de memória

23

function IndexChar( const buf; len: SizeInt; b: Char):SizeInt;

Encontra o valor do tamanho de char em um intervalo de memória

24

function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt;

Encontra um valor de tamanho DWord (32 bits) em um intervalo de memória

25

function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt;

Encontra o valor de tamanho QWord em um intervalo de memória

26

function Indexword( const buf; len: SizeInt; b: Word):SizeInt;

Encontra o valor do tamanho da palavra em um intervalo de memória

27

function IsMemoryManagerSet: Boolean;

O gerenciador de memória está definido

28

function Low( Arg: TypeOrVariable ):TOrdinal;

Retorna o índice mais baixo de matriz aberta ou enumerada

29

procedure Move( const source; var dest; count: SizeInt );

Move dados de um local da memória para outro

30

procedure MoveChar0( const buf1; var buf2; len: SizeInt);

Move os dados até o primeiro caractere zero

31

procedure New( var P: Pointer);

Alocar memória dinamicamente para a variável

32

procedure New( var P: Pointer; Cons: TProcedure);

Aloca memória dinamicamente para variável

33

function Ofs( var X ):LongInt;

Retorna o deslocamento da variável

34

function ptr( sel: LongInt; off: LongInt):farpointer;

Combina segmento e deslocamento para ponteiro

35

function ReAllocMem( var p: pointer; Size: PtrUInt):pointer;

Redimensiona um bloco de memória na pilha

36

function Seg( var X):LongInt;

Retorna segmento

37

procedure SetMemoryManager( const MemMgr: TMemoryManager );

Define um gerenciador de memória

38

function Sptr: Pointer;

Retorna o ponteiro da pilha atual

39

function Sseg: Word;

Retorna o valor do registro do segmento da pilha