Pascal - Memory Management
This chapter explains dynamic memory management in Pascal. Pascal programming language provides several functions for memory allocation and management.
Allocating Memory Dynamically
While doing programming, if you are aware about the size of an array, then it is easy and you can define it as an array. For example to store a name of any person, it can go max 100 characters so you can define something as follows:
var name: array[1..100] of char;
But now let us consider a situation where you have no idea about the length of the text you need to store, for example you want to store a detailed description about a topic. Here we need to define a pointer to string without defining how much memory is required.
Pascal provides a procedure new to create pointer variables.
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^); readln; // to see the output end.
When the above code is compiled and executed, it produces following result:
Name = Zara Ali Description: Zara ali a DPS student in class 10th
Now, if you need to define a pointer with specific number of bytes to be referred by it later, you should use the getmem function or the getmem procedure, which has the following syntax:
procedure Getmem(out p: pointer; Size:PtrUInt); function GetMem(size:PtrUInt):pointer;
In the previous example, we declared a pointer to a string. A string has a maximum value of 255 bytes. If you really don't need that much space, or a larger space, in terms of bytes, getmem subprogram allows specifying that. Let us rewrite the previous example, using 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); readln; // to see the output end.
When the above code is compiled and executed, it produces following result:
Name = Zara Ali Description: Zara ali a DPS student in class 10th
So you have complete control and you can pass any size value while allocating memory unlike arrays where once you defined the size cannot be changed.
Resizing and Releasing Memory
When your program comes out, operating system automatically release all the memory allocated by your program but as a good practice when you are not in need of memory anymore then you should release that memory.
Pascal provides the procedure dispose to free a dynamically created variable using the procedure new. If you have allocated memory using the getmemsubprogram, then you need to use the subprogram freemem to free this memory. The freemem subprograms have the following syntax:
procedure Freemem(p: pointer; Size:PtrUInt); function Freemem(p: pointer):PtrUInt;
Alternatively, you can increase or decrease the size of an allocated memory block by calling the function ReAllocMem. Let us check the above program once again and make use of ReAllocMem and freemem subprograms. Following is the syntax for ReAllocMem:
functionReAllocMem(var p: pointer; Size:PtrUInt):pointer;
Following is an example which makes use of ReAllocMem and freemem subprograms:
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); readln; // to see the output end.
When the above code is compiled and executed, it produces following result:
Name = Zara Ali Description: Zara ali a DPS student. She is in class 10th
Memory Management Functions
Pascal provides a hoard of memory management functions that is used in implementing various data structures and implementing low level programming in Pascal. Many of these functions are implementation dependent. Free Pascal provides the following functions and procedure for memory management:
S.N | Function Name & Description |
---|---|
1 | function Addr(X: TAnytype):Pointer; Return address of variable |
2 | function Assigned(P: Pointer):Boolean; Check if a pointer is valid |
3 | function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt; Compare 2 memory buffers byte per byte |
4 | function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt; Compare 2 memory buffers byte per byte |
5 | function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt; Compare 2 memory buffers byte per byte |
6 | function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt; Compare 2 memory buffers byte per byte |
7 | function Cseg: Word; Return code segment |
8 | procedure Dispose(P: Pointer); Free dynamically allocated memory |
9 | procedure Dispose(P: TypedPointer; Des: TProcedure); Free dynamically allocated memory |
10 | function Dseg: Word; Return data segment |
11 | procedure FillByte(var x; count: SizeInt; value: Byte); Fill memory region with 8-bit pattern |
12 | procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char); Fill memory region with certain character |
13 | procedure FillDWord( var x; count: SizeInt; value: DWord); Fill memory region with 32-bit pattern |
14 | procedure FillQWord( var x; count: SizeInt; value: QWord); Fill memory region with 64-bit pattern |
15 | procedure FillWord( var x; count: SizeInt; Value: Word); Fill memory region with 16-bit pattern |
16 | procedure Freemem( p: pointer; Size: PtrUInt); Release allocated memory |
17 | procedure Freemem( p: pointer ); Release allocated memory |
18 | procedure Getmem( out p: pointer; Size: PtrUInt); Allocate new memory |
19 | procedure Getmem( out p: pointer); Allocate new memory |
20 | procedure GetMemoryManager( var MemMgr: TMemoryManager); Return current memory manager |
21 | function High( Arg: TypeOrVariable):TOrdinal; Return highest index of open array or enumerated |
22 | function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt; Find byte-sized value in a memory range |
23 | function IndexChar( const buf; len: SizeInt; b: Char):SizeInt; Find char-sized value in a memory range |
24 | function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt; Find DWord-sized (32-bit) value in a memory range |
25 | function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt; Find QWord-sized value in a memory range |
26 | function Indexword( const buf; len: SizeInt; b: Word):SizeInt; Find word-sized value in a memory range |
27 | function IsMemoryManagerSet: Boolean; Is the memory manager set |
28 | function Low( Arg: TypeOrVariable ):TOrdinal; Return lowest index of open array or enumerated |
29 | procedure Move( const source; var dest; count: SizeInt ); Move data from one location in memory to another |
30 | procedure MoveChar0( const buf1; var buf2; len: SizeInt); Move data till first zero character |
31 | procedure New( var P: Pointer); Dynamically allocate memory for variable |
32 | procedure New( var P: Pointer; Cons: TProcedure); Dynamically allocate memory for variable |
33 | function Ofs( var X ):LongInt; Return offset of variable |
34 | function ptr( sel: LongInt; off: LongInt):farpointer; Combine segment and offset to pointer |
35 | function ReAllocMem( var p: pointer; Size: PtrUInt):pointer; Resize a memory block on the heap |
36 | function Seg( var X):LongInt; Return segment |
37 | procedure SetMemoryManager( const MemMgr: TMemoryManager ); Set a memory manager |
38 | function Sptr: Pointer; Return current stack pointer |
39 | function Sseg: Word; Return stack segment register value |