Pascal - Zarządzanie pamięcią
Ten rozdział wyjaśnia dynamiczne zarządzanie pamięcią w Pascalu. Język programowania Pascal zapewnia kilka funkcji do przydzielania i zarządzania pamięcią.
Dynamiczne przydzielanie pamięci
Podczas programowania, jeśli jesteś świadomy rozmiaru tablicy, jest to łatwe i możesz zdefiniować ją jako tablicę. Na przykład, aby zapisać imię i nazwisko dowolnej osoby, może mieć maksymalnie 100 znaków, więc możesz zdefiniować coś w następujący sposób -
var
name: array[1..100] of char;
Ale teraz rozważmy sytuację, w której nie masz pojęcia o długości tekstu, który chcesz przechowywać, na przykład chcesz przechowywać szczegółowy opis tematu. Tutaj musimy zdefiniować wskaźnik do łańcucha bez definiowania wymaganej ilości pamięci.
Pascal zapewnia procedurę newdo tworzenia zmiennych wskaźnikowych.
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.
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Name = Zara Ali
Description: Zara ali a DPS student in class 10th
Teraz, jeśli chcesz zdefiniować wskaźnik z określoną liczbą bajtów, do których ma on się później odwoływać, powinieneś użyć getmem funkcja lub getmem procedura, która ma następującą składnię -
procedure Getmem(
out p: pointer;
Size: PtrUInt
);
function GetMem(
size: PtrUInt
):pointer;
W poprzednim przykładzie zadeklarowaliśmy wskaźnik do łańcucha. Ciąg ma maksymalną wartość 255 bajtów. Jeśli naprawdę nie potrzebujesz tak dużo miejsca lub większej przestrzeni pod względem bajtów, podprogram getmem pozwala to określić. Przepiszmy poprzedni przykład, używając 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.
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Name = Zara Ali
Description: Zara ali a DPS student in class 10th
Masz więc pełną kontrolę i możesz przekazać dowolną wartość rozmiaru podczas przydzielania pamięci, w przeciwieństwie do tablic, w których raz zdefiniowanego rozmiaru nie można zmienić.
Zmiana rozmiaru i zwalnianie pamięci
Kiedy program się pojawia, system operacyjny automatycznie zwalnia całą pamięć przydzieloną przez program, ale jako dobrą praktykę, gdy nie potrzebujesz już pamięci, powinieneś zwolnić tę pamięć.
Pascal zapewnia procedurę dispose aby zwolnić dynamicznie utworzoną zmienną za pomocą procedury new. Jeśli przydzieliłeś pamięć za pomocą getmem podprogramu, musisz użyć podprogramu freememaby uwolnić tę pamięć. W freemem podprogramy mają następującą składnię -
procedure Freemem(
p: pointer;
Size: PtrUInt
);
function Freemem(
p: pointer
):PtrUInt;
Alternatywnie możesz zwiększyć lub zmniejszyć rozmiar przydzielonego bloku pamięci, wywołując funkcję ReAllocMem . Sprawdźmy jeszcze raz powyższy program i skorzystajmy z podprogramów ReAllocMem i freemem . Poniżej znajduje się składnia ReAllocMem -
function ReAllocMem(
var p: pointer;
Size: PtrUInt
):pointer;
Poniżej znajduje się przykład wykorzystujący podprogramy ReAllocMem i 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.
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Name = Zara Ali
Description: Zara ali a DPS student. She is in class 10th
Funkcje zarządzania pamięcią
Pascal zapewnia mnóstwo funkcji zarządzania pamięcią, które są używane do implementacji różnych struktur danych i implementacji programowania niskiego poziomu w Pascalu. Wiele z tych funkcji jest zależnych od implementacji. Free Pascal zapewnia następujące funkcje i procedury zarządzania pamięcią -
SN | Nazwa i opis funkcji |
---|---|
1 | function Addr(X: TAnytype):Pointer; Zwraca adres zmiennej |
2 | function Assigned(P: Pointer):Boolean; Sprawdza, czy wskaźnik jest prawidłowy |
3 | function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt; Porównuje 2 bajty buforów pamięci na bajt |
4 | function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt; Porównuje 2 bajty buforów pamięci na bajt |
5 | function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt; Porównuje 2 bajty buforów pamięci na bajt |
6 | function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt; Porównuje 2 bajty buforów pamięci na bajt |
7 | function Cseg: Word; Zwraca segment kodu |
8 | procedure Dispose(P: Pointer); Zwalnia dynamicznie alokowaną pamięć |
9 | procedure Dispose(P: TypedPointer; Des: TProcedure); Zwalnia dynamicznie alokowaną pamięć |
10 | function Dseg: Word; Zwraca segment danych |
11 | procedure FillByte(var x; count: SizeInt; value: Byte); Wypełnia obszar pamięci 8-bitowym wzorem |
12 | procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char); Wypełnia obszar pamięci określonym charakterem |
13 | procedure FillDWord( var x; count: SizeInt; value: DWord); Wypełnia obszar pamięci wzorcem 32-bitowym |
14 | procedure FillQWord( var x; count: SizeInt; value: QWord); Wypełnia obszar pamięci wzorcem 64-bitowym |
15 | procedure FillWord( var x; count: SizeInt; Value: Word); Wypełnia obszar pamięci 16-bitowym wzorem |
16 | procedure Freemem( p: pointer; Size: PtrUInt); Zwalnia przydzieloną pamięć |
17 | procedure Freemem( p: pointer ); Zwalnia przydzieloną pamięć |
18 | procedure Getmem( out p: pointer; Size: PtrUInt); Przydziela nową pamięć |
19 | procedure Getmem( out p: pointer); Przydziela nową pamięć |
20 | procedure GetMemoryManager( var MemMgr: TMemoryManager); Zwraca aktualny menedżer pamięci |
21 | function High( Arg: TypeOrVariable):TOrdinal; Zwraca najwyższy indeks otwartej tablicy lub wyliczoną |
22 | function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt; Znajduje wartość o rozmiarze bajtu w zakresie pamięci |
23 | function IndexChar( const buf; len: SizeInt; b: Char):SizeInt; Znajduje wartość o rozmiarze znaku w zakresie pamięci |
24 | function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt; Znajduje wartość o rozmiarze DWord (32-bitowa) w zakresie pamięci |
25 | function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt; Znajduje wartość wielkości QWord w zakresie pamięci |
26 | function Indexword( const buf; len: SizeInt; b: Word):SizeInt; Znajduje wartość wielkości słowa w zakresie pamięci |
27 | function IsMemoryManagerSet: Boolean; Czy menedżer pamięci jest ustawiony |
28 | function Low( Arg: TypeOrVariable ):TOrdinal; Zwraca najniższy indeks otwartej tablicy lub wyliczenie |
29 | procedure Move( const source; var dest; count: SizeInt ); Przenosi dane z jednego miejsca w pamięci do drugiego |
30 | procedure MoveChar0( const buf1; var buf2; len: SizeInt); Przenosi dane do pierwszego znaku zera |
31 | procedure New( var P: Pointer); Dynamicznie przydziel pamięć dla zmiennej |
32 | procedure New( var P: Pointer; Cons: TProcedure); Dynamicznie przydziela pamięć dla zmiennej |
33 | function Ofs( var X ):LongInt; Zwraca przesunięcie zmiennej |
34 | function ptr( sel: LongInt; off: LongInt):farpointer; Łączy segment i odsunięcie ze wskaźnikiem |
35 | function ReAllocMem( var p: pointer; Size: PtrUInt):pointer; Zmienia rozmiar bloku pamięci na stercie |
36 | function Seg( var X):LongInt; Segment zwrotów |
37 | procedure SetMemoryManager( const MemMgr: TMemoryManager ); Ustawia menedżera pamięci |
38 | function Sptr: Pointer; Zwraca bieżący wskaźnik stosu |
39 | function Sseg: Word; Zwraca wartość rejestru segmentu stosu |