Pascal - 記憶體管理



本章解釋了 Pascal 中的動態記憶體管理。Pascal 程式語言提供了多個用於記憶體分配和管理的函式。

動態分配記憶體

在程式設計過程中,如果您知道陣列的大小,那麼定義陣列就很容易了。例如,要儲存任何人的姓名,最多可以有 100 個字元,因此您可以定義如下內容:

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

但是現在,讓我們考慮一種情況,您不知道需要儲存的文字長度,例如,您想儲存關於某個主題的詳細描述。在這裡,我們需要定義一個指向字串的指標,而無需定義需要多少記憶體。

Pascal 提供了一個過程 `new` 來建立指標變數。

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.

編譯並執行上述程式碼後,將產生以下結果:

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

現在,如果您需要定義一個指標,並讓它稍後引用特定數量的位元組,則應使用 `getmem` 函式或 `getmem` 過程,其語法如下:

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

function GetMem(
   size: PtrUInt
):pointer;

在前面的示例中,我們聲明瞭一個指向字串的指標。字串的最大值為 255 個位元組。如果您真的不需要那麼多空間,或者需要更大的空間(以位元組為單位),`getmem` 子程式允許指定該空間。讓我們使用 `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.

編譯並執行上述程式碼後,將產生以下結果:

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

因此,您可以完全控制,並且可以在分配記憶體時傳遞任何大小的值,這與陣列不同,陣列一旦定義了大小就無法更改。

調整和釋放記憶體

程式退出時,作業系統會自動釋放程式分配的所有記憶體,但是,作為一個良好的實踐,如果您不再需要記憶體,則應該釋放該記憶體。

Pascal 提供了 `dispose` 過程來使用 `new` 過程釋放動態建立的變數。如果您使用 `getmem` 子程式分配了記憶體,則需要使用 `freemem` 子程式來釋放此記憶體。`freemem` 子程式的語法如下:

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

function Freemem(
   p: pointer
):PtrUInt;

或者,您可以透過呼叫 `ReAllocMem` 函式來增加或減少已分配記憶體塊的大小。讓我們再次檢查上面的程式,並使用 `ReAllocMem` 和 `freemem` 子程式。以下是 `ReAllocMem` 的語法:

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

以下是一個使用 `ReAllocMem` 和 `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.

編譯並執行上述程式碼後,將產生以下結果:

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

記憶體管理函式

Pascal 提供了許多記憶體管理函式,這些函式用於實現各種資料結構並在 Pascal 中實現低階程式設計。許多這些函式是實現相關的。Free Pascal 提供了以下用於記憶體管理的函式和過程:

序號 函式名稱和描述
1

function Addr(X: TAnytype):Pointer;

返回變數的地址

2

function Assigned(P: Pointer):Boolean;

檢查指標是否有效

3

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

逐位元組比較兩個記憶體緩衝區

4

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

逐位元組比較兩個記憶體緩衝區

5

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

逐位元組比較兩個記憶體緩衝區

6

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

逐位元組比較兩個記憶體緩衝區

7

function Cseg: Word;

返回程式碼段

8

procedure Dispose(P: Pointer);

釋放動態分配的記憶體

9

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

釋放動態分配的記憶體

10

function Dseg: Word;

返回資料段

11

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

用 8 位模式填充記憶體區域

12

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

用特定字元填充記憶體區域

13

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

用 32 位模式填充記憶體區域

14

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

用 64 位模式填充記憶體區域

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

用 16 位模式填充記憶體區域

16

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

釋放已分配的記憶體

17

procedure Freemem( p: pointer );

釋放已分配的記憶體

18

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

分配新記憶體

19

procedure Getmem( out p: pointer);

分配新記憶體

20

procedure GetMemoryManager( var MemMgr: TMemoryManager);

返回當前記憶體管理器

21

function High( Arg: TypeOrVariable):TOrdinal;

返回開放陣列或列舉的最高索引

22

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

在記憶體範圍內查詢位元組大小的值

23

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

在記憶體範圍內查詢字元大小的值

24

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

在記憶體範圍內查詢 DWord 大小(32 位)的值

25

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

在記憶體範圍內查詢 QWord 大小的值

26

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

在記憶體範圍內查詢字大小的值

27

function IsMemoryManagerSet: Boolean;

記憶體管理器是否已設定

28

function Low( Arg: TypeOrVariable ):TOrdinal;

返回開放陣列或列舉的最低索引

29

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

將資料從記憶體中的一個位置移動到另一個位置

30

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

移動資料到第一個零字元

31

procedure New( var P: Pointer);

為變數動態分配記憶體

32

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

為變數動態分配記憶體

33

function Ofs( var X ):LongInt;

返回變數的偏移量

34

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

將段和偏移量組合成指標

35

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

調整堆上的記憶體塊大小

36

function Seg( var X):LongInt;

返回段

37

procedure SetMemoryManager( const MemMgr: TMemoryManager );

設定記憶體管理器

38

function Sptr: Pointer;

返回當前堆疊指標

39

function Sseg: Word;

返回堆疊段暫存器值

廣告