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 จัดเตรียมฟังก์ชันการจัดการหน่วยความจำที่ใช้ในการนำโครงสร้างข้อมูลต่างๆไปใช้และการเขียนโปรแกรมระดับต่ำในภาษาปาสคาล หลายฟังก์ชันเหล่านี้ขึ้นอยู่กับการใช้งาน Free Pascal มีฟังก์ชันและขั้นตอนการจัดการหน่วยความจำดังต่อไปนี้ -
SN | ชื่อฟังก์ชันและคำอธิบาย |
---|---|
1 | function Addr(X: TAnytype):Pointer; ส่งกลับที่อยู่ของตัวแปร |
2 | function Assigned(P: Pointer):Boolean; ตรวจสอบว่าตัวชี้ถูกต้องหรือไม่ |
3 | function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt; เปรียบเทียบหน่วยความจำบัฟเฟอร์ 2 ไบต์ต่อไบต์ |
4 | function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt; เปรียบเทียบหน่วยความจำบัฟเฟอร์ 2 ไบต์ต่อไบต์ |
5 | function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt; เปรียบเทียบหน่วยความจำบัฟเฟอร์ 2 ไบต์ต่อไบต์ |
6 | function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt; เปรียบเทียบหน่วยความจำบัฟเฟอร์ 2 ไบต์ต่อไบต์ |
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; ส่งคืนค่าทะเบียนเซ็กเมนต์สแต็ก |