Pascal - Gestione della memoria

Questo capitolo spiega la gestione dinamica della memoria in Pascal. Il linguaggio di programmazione Pascal fornisce diverse funzioni per l'allocazione e la gestione della memoria.

Allocazione dinamica della memoria

Durante la programmazione, se si è consapevoli della dimensione di un array, è facile e lo si può definire come array. Ad esempio, per memorizzare un nome di qualsiasi persona, può contenere al massimo 100 caratteri in modo da poter definire qualcosa come segue:

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

Ma ora, consideriamo una situazione in cui non hai idea della lunghezza del testo che devi memorizzare, ad esempio, vuoi memorizzare una descrizione dettagliata su un argomento. Qui, dobbiamo definire un puntatore a una stringa senza definire la quantità di memoria richiesta.

Pascal fornisce una procedura newper creare variabili puntatore.

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 il codice precedente viene compilato ed eseguito, produce il seguente risultato:

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

Ora, se è necessario definire un puntatore con un numero specifico di byte a cui fare riferimento in seguito, è necessario utilizzare il getmem funzione o il getmem procedura, che ha la seguente sintassi:

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

function GetMem(
   size: PtrUInt
):pointer;

Nell'esempio precedente, abbiamo dichiarato un puntatore a una stringa. Una stringa ha un valore massimo di 255 byte. Se davvero non hai bisogno di tanto spazio, o uno spazio più grande, in termini di byte, il sottoprogramma getmem consente di specificarlo. Riscriviamo l' esempio precedente, 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 il codice precedente viene compilato ed eseguito, produce il seguente risultato:

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

Quindi, hai il controllo completo e puoi passare qualsiasi valore di dimensione durante l'allocazione della memoria a differenza degli array, dove una volta definita la dimensione non può essere modificata.

Ridimensionamento e rilascio della memoria

Quando il tuo programma esce, il sistema operativo rilascia automaticamente tutta la memoria allocata dal tuo programma, ma come buona pratica quando non hai più bisogno di memoria, dovresti rilasciare quella memoria.

Pascal fornisce la procedura dispose per liberare una variabile creata dinamicamente utilizzando la procedura new. Se hai allocato memoria utilizzando il file getmem sottoprogramma, quindi è necessario utilizzare il sottoprogramma freememper liberare questa memoria. I sottoprogrammi freemem hanno la seguente sintassi:

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

function Freemem(
   p: pointer
):PtrUInt;

In alternativa, è possibile aumentare o diminuire la dimensione di un blocco di memoria allocato chiamando la funzione ReAllocMem . Controlliamo ancora una volta il programma precedente e utilizziamo ReAllocMem e sottoprogrammi freemem . Di seguito è riportata la sintassi per ReAllocMem :

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

Di seguito è riportato un esempio che utilizza i sottoprogrammi ReAllocMem e 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.

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

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

Funzioni di gestione della memoria

Pascal fornisce un tesoro di funzioni di gestione della memoria che viene utilizzato nell'implementazione di varie strutture di dati e nell'implementazione della programmazione di basso livello in Pascal. Molte di queste funzioni dipendono dall'implementazione. Free Pascal fornisce le seguenti funzioni e procedure per la gestione della memoria:

SN Nome e descrizione della funzione
1

function Addr(X: TAnytype):Pointer;

Restituisce l'indirizzo della variabile

2

function Assigned(P: Pointer):Boolean;

Controlla se un puntatore è valido

3

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

Confronta 2 buffer di memoria byte per byte

4

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

Confronta 2 buffer di memoria byte per byte

5

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

Confronta 2 buffer di memoria byte per byte

6

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

Confronta 2 buffer di memoria byte per byte

7

function Cseg: Word;

Restituisce il segmento di codice

8

procedure Dispose(P: Pointer);

Libera la memoria allocata dinamicamente

9

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

Libera la memoria allocata dinamicamente

10

function Dseg: Word;

Restituisce il segmento di dati

11

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

Riempie la regione di memoria con un pattern a 8 bit

12

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

Riempie la regione della memoria con un certo carattere

13

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

Riempie la regione di memoria con pattern a 32 bit

14

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

Riempie la regione di memoria con pattern a 64 bit

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

Riempie la regione di memoria con pattern a 16 bit

16

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

Rilascia la memoria allocata

17

procedure Freemem( p: pointer );

Rilascia la memoria allocata

18

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

Alloca nuova memoria

19

procedure Getmem( out p: pointer);

Alloca nuova memoria

20

procedure GetMemoryManager( var MemMgr: TMemoryManager);

Restituisce il gestore della memoria corrente

21

function High( Arg: TypeOrVariable):TOrdinal;

Restituisce l'indice più alto di matrice aperta o enumerata

22

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

Trova un valore della dimensione di byte in un intervallo di memoria

23

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

Trova un valore della dimensione di un carattere in un intervallo di memoria

24

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

Trova un valore di dimensione DWord (32 bit) in un intervallo di memoria

25

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

Trova un valore di dimensione QWord in un intervallo di memoria

26

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

Trova un valore a dimensione di parola in un intervallo di memoria

27

function IsMemoryManagerSet: Boolean;

È impostato il gestore della memoria

28

function Low( Arg: TypeOrVariable ):TOrdinal;

Restituisce l'indice più basso dell'array aperto o enumerato

29

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

Sposta i dati da una posizione in memoria a un'altra

30

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

Sposta i dati fino al primo carattere zero

31

procedure New( var P: Pointer);

Alloca dinamicamente la memoria per la variabile

32

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

Alloca dinamicamente la memoria per la variabile

33

function Ofs( var X ):LongInt;

Restituisce l'offset della variabile

34

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

Combina segmento e offset al puntatore

35

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

Ridimensiona un blocco di memoria nell'heap

36

function Seg( var X):LongInt;

Restituisce segmento

37

procedure SetMemoryManager( const MemMgr: TMemoryManager );

Imposta un gestore della memoria

38

function Sptr: Pointer;

Restituisce il puntatore allo stack corrente

39

function Sseg: Word;

Restituisce il valore del registro del segmento dello stack