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 |