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