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:= 'Alex Mo';
       
       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 = Alex Mo
    Description:Alex Mo 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:= 'Alex Mo';
       
       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 = Alex Mo
    Description:Alex Mo a DPS student in class 10th
    
    因此,您拥有完全的控制权,并且可以在分配内存的同时传递任何大小值,而与数组不同,在数组中,一旦定义大小就无法更改。
  • 调整大小和释放内存

    当您的程序发布时,操作系统会自动释放程序分配的所有内存,但是作为一种好习惯,当您不再需要内存时,则应该释放该内存。帕斯卡提供程序处置使用过程以释放动态创建的变量新。如果使用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;  
    
    以下是使用ReAllocMem和freemem子程序的示例-
    
    program exMemory;
    var
    name: array[1..100] of char;
    description: ^string;
    desp: string;
    
    begin
       name:= 'Alex Mo';
       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 = Alex Mo
    Description:Alex Mo a DPS student. She is in class 10th
    
  • 内存管理函数

    Pascal 提供了大量的内存管理函数,可用于实现各种数据结构以及在Pascal中实现低级编程。其中许多函数都依赖于实现。Free Pascal提供以下用于内存管理的函数和过程-
    函数/过程 说明
    function Addr(X: TAnytype):Pointer; 返回变量的地址
    function Assigned(P: Pointer):Boolean; 检查指针是否有效
    function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt; 比较每个字节2个内存缓冲区
    function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt; 比较每个字节2个内存缓冲区
    function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt; 比较每个字节2个内存缓冲区
    function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt; 比较每个字节2个内存缓冲区
    function Cseg: Word; 返回代码段
    procedure Dispose(P: Pointer); 释放动态分配的内存
    procedure Dispose(P: TypedPointer; Des: TProcedure); 释放动态分配的内存
    function Dseg: Word; 返回数据段
    procedure FillByte(var x; count: SizeInt; value: Byte); 用8位模式填充存储区
    procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char); 用某些字符填充存储区
    procedure FillDWord( var x; count: SizeInt; value: DWord); 用32位模式填充内存区域
    procedure FillQWord( var x; count: SizeInt; value: QWord); 用64位模式填充内存区域
    procedure FillWord( var x; count: SizeInt; Value: Word); 用16位模式填充存储区
    procedure Freemem( p: pointer; Size: PtrUInt); 释放分配的内存
    procedure Freemem( p: pointer ); 释放分配的内存
    procedure Getmem( out p: pointer; Size: PtrUInt); 分配新内存
    procedure Getmem( out p: pointer); 分配新内存
    procedure GetMemoryManager( var MemMgr: TMemoryManager); 返回当前的内存管理器
    function High( Arg: TypeOrVariable):TOrdinal; 返回开放数组的最高索引或枚举
    function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt; 在内存范围内查找字节大小的值
    function IndexChar( const buf; len: SizeInt; b: Char):SizeInt; 在内存范围内查找字符大小的值
    function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt; 在内存范围内查找DWord大小(32位)的值
    function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt; 在内存范围内查找QWord大小的值
    function Indexword( const buf; len: SizeInt; b: Word):SizeInt; 在存储范围内查找单词大小的值
    function IsMemoryManagerSet: Boolean; 是否设置了内存管理器
    function Low( Arg: TypeOrVariable ):TOrdinal; 返回开放数组的最低索引或枚举
    procedure Move( const source; var dest; count: SizeInt ); 将数据从内存中的一个位置移动到另一位置
    procedure MoveChar0( const buf1; var buf2; len: SizeInt); 移动数据直到第一个零字符
    procedure New( var P: Pointer); 动态为变量分配内存
    procedure New( var P: Pointer; Cons: TProcedure); 动态为变量分配内存
    function Ofs( var X ):LongInt; 返回变量的偏移量
    function ptr( sel: LongInt; off: LongInt):farpointer; 将段和偏移量组合到指针
    function ReAllocMem( var p: pointer; Size: PtrUInt):pointer; 调整堆上的内存块大小
    function Seg( var X):LongInt; 返回细分
    procedure SetMemoryManager( const MemMgr: TMemoryManager ); 设置一个内存管理器
    function Sptr: Pointer; 返回当前堆栈指针
    function Sseg: Word; 返回堆栈段寄存器值