帕斯卡 - 内存管理


本章介绍 Pascal 中的动态内存管理。Pascal 编程语言提供了多种内存分配和管理函数。

动态分配内存

在编程时,如果您知道数组的大小,那么很容易,您可以将其定义为数组。例如,要存储任何人的姓名,最多可以包含 100 个字符,因此您可以定义如下内容 -

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

但是现在,让我们考虑一种情况,您不知道需要存储的文本的长度,例如,您想存储有关某个主题的详细描述。这里,我们需要定义一个指向字符串的指针,而不定义需要多少内存。

Pascal 提供了一个新的过程来创建指针变量。

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来增加或减少已分配内存块的大小。让我们再次检查上面的程序并使用ReAllocMemfreemem子程序。以下是ReAllocMem的语法-

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

以下是使用ReAllocMemfreemem子程序的示例 -

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

函数Addr(X:TAnytype):指针;

返回变量的地址

2

函数分配(P:指针):布尔值;

检查指针是否有效

3

函数 CompareByte(const buf1; const buf2; len: SizeInt):SizeInt;

每个字节比较 2 个内存缓冲区

4

函数 CompareChar(const buf1; const buf2; len: SizeInt):SizeInt;

每个字节比较 2 个内存缓冲区

5

函数 CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt;

每个字节比较 2 个内存缓冲区

6

函数 CompareWord(const buf1; const buf2; len: SizeInt):SizeInt;

每个字节比较 2 个内存缓冲区

7

函数 Cseg:Word;

返回代码段

8

过程 Dispose(P: 指针);

释放动态分配的内存

9

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

释放动态分配的内存

10

函数Dseg:字;

返回数据段

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: 指针; 大小: PtrUInt);

释放分配的内存

17 号

过程 Freemem( p: 指针 );

释放分配的内存

18

procedure Getmem( out p: 指针; Size: PtrUInt);

分配新内存

19

procedure Getmem( out p: 指针);

分配新内存

20

过程 GetMemoryManager( var MemMgr: TMemoryManager);

返回当前内存管理器

21

函数 High( Arg: TypeOrVariable):TORdinal;

返回开放数组或枚举的最高索引

22

函数 IndexByte( const buf; len: SizeInt; b: Byte):SizeInt;

在内存范围中查找字节大小的值

23

函数 IndexChar( const buf; len: SizeInt; b: Char):SizeInt;

在内存范围内查找字符大小的值

24

函数 IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt;

查找内存范围中的双字大小(32 位)值

25

函数 IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt;

在内存范围内查找 QWord 大小的值

26

函数 Indexword( const buf; len: SizeInt; b: Word):SizeInt;

在内存范围内查找字大小的值

27

函数 IsMemoryManagerSet:布尔值;

内存管理器是否设置

28

函数 Low( Arg: TypeOrVariable ):TORdinal;

返回开放数组或枚举的最低索引

29

过程 Move( const source; var dest; count: SizeInt );

将数据从内存中的一个位置移动到另一位置

30

过程 MoveChar0( const buf1; var buf2; len: SizeInt);

将数据移动到第一个零字符

31

procedure New( var P: 指针);

动态为变量分配内存

32

procedure New( var P: 指针; Cons: TProcedure);

动态为变量分配内存

33

函数 Ofs( var X ):LongInt;

返回变量的偏移量

34

函数 ptr( sel: LongInt; off: LongInt):farpointer;

将段和偏移量组合到指针

35

function ReAllocMem( var p: 指针; 大小: PtrUInt): 指针;

调整堆上内存块的大小

36

函数 Seg( var X):LongInt;

返回段

37

程序 SetMemoryManager( const MemMgr: TMemoryManager );

设置内存管理器

38

函数 Sptr:指针;

返回当前堆栈指针

39

函数 Sseg:Word;

返回堆栈段寄存器值