การทำความเข้าใจหน่วยความจำแบบสแต็กและฮีปถือเป็นสิ่งสำคัญสำหรับการเขียนโปรแกรมที่มีประสิทธิภาพและเชื่อถือได้
ในภาษา C, C++ และ Java หน่วยความจำสามารถจัดสรรได้ทั้งในรูปแบบสแต็กหรือฮีปการจัดสรรแบบสแต็กเกิดขึ้นในสแต็กการเรียกฟังก์ชันโดยแต่ละฟังก์ชันจะได้รับหน่วยความจำของตัวเองสำหรับตัวแปร ในภาษา C/C++ หน่วยความจำแบบฮีปนั้นถูกควบคุมโดยโปรแกรมเมอร์ เนื่องจากไม่มีการเก็บขยะอัตโนมัติ
การจัดสรรหน่วยความจำแบบ Stack หมายถึงกระบวนการจัดสรรหน่วยความจำให้กับตัวแปรโลคอลและการเรียกฟังก์ชันในCall Stackกระบวนการนี้เกิดขึ้นโดยอัตโนมัติเมื่อมีการเรียกฟังก์ชัน และจะถูกปล่อยคืนทันทีเมื่อฟังก์ชันสิ้นสุดลง เนื่องจากระบบเป็นผู้จัดการหน่วยความจำ จึงรวดเร็วและมีประสิทธิภาพแต่มีพื้นที่จำกัดเมื่อเทียบกับการจัดสรรหน่วยความจำแบบ Heap หากมีการเรียกฟังก์ชันมากเกินไปจนเกินความจุของ Stack จะทำให้เกิด ข้อผิด พลาดStack Overflow
ตัวอย่างโค้ด:
int main() {
// All these variables get memory
// allocated on stack
int a;
int b[10];
int n = 20;
int c[n];
}หน่วยความจำฮีปจะถูกจัดสรรแบบไดนามิกในระหว่างการทำงานของโปรแกรม แตกต่างจากหน่วยความจำสแต็กหน่วยความจำฮีปจะไม่ถูกปล่อยโดยอัตโนมัติเมื่อฟังก์ชันสิ้นสุดลง แต่จะต้องมีการปล่อยหน่วยความจำด้วยตนเอง (ในภาษา C/C++)หรือใช้ตัวเก็บขยะ (ในภาษา Java หรือ Python)เพื่อเรียกคืนหน่วยความจำที่ไม่ได้ใช้งาน
ชื่อ"ฮีป"ไม่ได้มีความเกี่ยวข้องกับโครงสร้างข้อมูลแบบฮีปแต่อย่างใด มันหมายถึงเพียงแค่กลุ่มหน่วยความจำขนาดใหญ่ที่พร้อมสำหรับการจัดสรรแบบไดนามิกเมื่อใดก็ตามที่มีการสร้างวัตถุ วัตถุ นั้นจะถูกจัดเก็บไว้ใน หน่วยความจำฮีปในขณะที่การอ้างอิงถึงวัตถุเหล่านั้นจะถูกจัดเก็บไว้ในหน่วยความจำสแต็กการจัดสรรหน่วยความจำแบบฮีปมีความปลอดภัยน้อยกว่าการจัดสรรแบบสแต็ก เนื่องจากข้อมูลในฮีปสามารถเข้าถึงได้โดยหลายเธรดซึ่งเพิ่มความเสี่ยงต่อการเสียหายของข้อมูลและการรั่วไหลของหน่วยความจำหากไม่ได้รับการจัดการอย่างเหมาะสม
หน่วยความจำฮีปถูกแบ่งออกเป็นสามประเภท ซึ่งช่วยในการจัดลำดับความสำคัญของการจัดเก็บวัตถุและการเก็บขยะ :
ตัวอย่างโค้ด:
int main()
{
// This memory for 10 integers
// is allocated on heap.
int *ptr = new int[10];
}เพื่อทำความเข้าใจความแตกต่างระหว่างการจัดสรรหน่วยความจำแบบสแต็กและฮีปโดยสังเกตวิธีการสร้างและจัดการวัตถุในทั้งสองกรณี โดยใช้คลาสEmpสำหรับจัดเก็บรายละเอียดพนักงาน
ด้านล่างนี้คือตัวอย่างการใช้งาน:
C++
#include <bits/stdc++.h>
using namespace std;
class Emp {
public:
int id;
string emp_name;
// Constructor to initialize employee details
Emp(int id, string emp_name) {
this->id = id;
this->emp_name = emp_name;
}
};
// Function to create and return an Emp object
Emp Emp_detail(int id, string emp_name) {
return Emp(id, emp_name);
}
int main() {
// Initializing employee details
int id = 21;
string name = "Maddy";
// Creating an Emp object using the function
Emp person_ = Emp_detail(id, name);
return 0;
}Java
class Emp {
int id;
String emp_name;
public Emp(int id, String emp_name) {
this.id = id;
this.emp_name = emp_name;
}
}
public class Emp_detail {
private static Emp Emp_detail(int id, String emp_name) {
return new Emp(id, emp_name);
}
public static void main(String[] args) {
int id = 21;
String name = "Maddy";
Emp person_ = null;
person_ = Emp_detail(id, name);
}
}Python
class Emp:
# Constructor to initialize employee details
def __init__(self, id, emp_name):
self.id = id
self.emp_name = emp_name
# Function to create and return an Emp object
def Emp_detail(id, emp_name):
return Emp(id, emp_name)
if __name__ == "__main__":
# Initializing employee details
id = 21
name = "Maddy"
# Creating an Emp object using the function
person_ = None
person_ = Emp_detail(id, name)JavaScript
class Emp {
// Constructor to initialize employee details
constructor(id, emp_name) {
this.id = id;
this.emp_name = emp_name;
}
}
// Function to create and return an Emp object
function Emp_detail(id, emp_name) {
return new Emp(id, emp_name);
}
// Initializing employee details
let id = 21;
let name = "Maddy";
// Creating an Emp object using the function
let person_ = null;
person_ = Emp_detail(id, name);จากตัวอย่างข้างต้น เราสามารถสรุปได้ดังนี้:
ภาพประกอบแสดงดังแผนภาพด้านล่าง: