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 |