การจัดสรรบนฮีพด้วย new/delete
จัดการหน่วยความจำแบบไดนามิก
การจัดสรรบนฮีพด้วย new/delete เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
หน่วยความจำแบบไดนามิกด้วยการจัดสรร
ตัวดำเนินการ new จะจัดสรรออบเจ็กต์บน ฮีป (พื้นที่จัดเก็บอิสระ) และคืนตัวชี้ไปยังออบเจ็กต์นั้น ออบเจ็กต์บนฮีปจะคงอยู่จนกว่าคุณจะคืนหน่วยความจำให้โดยชัดแจ้ง
#include <iostream>
int main() {
int* p = new int(42); // heap allocation
std::cout << *p << "\n";
delete p; // release it
}การคืนหน่วยความจำ
การใช้ new ทุกครั้งต้องจับคู่กับ delete เพียงหนึ่งครั้ง การลืมเรียกใช้จะทำให้เกิดการรั่วไหลของหน่วยความจำ ส่วนการเรียกใช้สองครั้งจะทำให้ฮีปเสียหาย
#include <iostream>
int main() {
double* d = new double(3.5);
std::cout << *d << "\n";
delete d; // exactly once
}อาร์เรย์: การจัดสรรและคืนหน่วยความจำ
สำหรับอาร์เรย์ โปรดใช้ new[] และ delete[] ที่เข้าคู่กัน การใช้ new[] ร่วมกับ delete แบบปกติเป็นพฤติกรรมที่ไม่ได้กำหนดไว้
#include <iostream>
int main() {
int* arr = new int[3]{1, 2, 3};
for (int i = 0; i < 3; ++i) std::cout << arr[i] << "\n";
delete[] arr; // note the [ ]
}เหตุใดจึงใช้ฮีป
โปรดใช้ฮีปเมื่อออบเจ็กต์ต้อง มีอายุยืนยาวกว่า ฟังก์ชันที่สร้างออบเจ็กต์นั้น หรือเมื่อทราบขนาดของออบเจ็กต์เฉพาะขณะโปรแกรมทำงานเท่านั้น หากไม่เข้าเงื่อนไขดังกล่าว โปรดเลือกใช้สแตก
อายุการใช้งานบนฮีปต้องจัดการเอง
ฮีปไม่คืนหน่วยความจำให้ออบเจ็กต์โดยอัตโนมัติเหมือนสแตก คุณเป็นผู้ควบคุมเวลาที่จะคืนหน่วยความจำอย่างแน่นอน และต้องรับผิดชอบการจัดการนี้เอง
#include <iostream>
int* makeCounter() {
return new int(0); // survives the function
}
int main() {
int* c = makeCounter();
std::cout << *c << "\n";
delete c;
}กำหนดตัวชี้เป็น nullptr หลังคืนหน่วยความจำ
หลังจากลบออบเจ็กต์แล้ว โปรดกำหนดตัวชี้เป็น nullptr เพื่อให้การนำตัวชี้ไปใช้โดยไม่ตั้งใจล้มเหลวอย่างชัดเจน แทนที่จะเข้าถึงหน่วยความจำที่คืนไปแล้ว
#include <iostream>
int main() {
int* p = new int(9);
delete p;
p = nullptr; // now p is safe to check
if (!p) std::cout << "freed\n";
}การจัดสรรอาจล้มเหลว
หากระบบไม่มีหน่วยความจำเหลือ new จะโยน std::bad_alloc สำหรับการจัดสรรขนาดใหญ่มาก เหตุการณ์นี้มีโอกาสเกิดขึ้นได้จริง
บัฟเฟอร์ที่มีขนาดตามเวลาทำงาน
อาร์เรย์บนฮีปสามารถใช้ขนาดที่คำนวณได้ขณะโปรแกรมทำงาน ซึ่งเป็นสิ่งที่อาร์เรย์บนสแตกไม่สามารถทำได้อย่างพกพาได้
#include <iostream>
int main() {
int n = 5;
int* buf = new int[n];
for (int i = 0; i < n; ++i) buf[i] = i * i;
std::cout << buf[4] << "\n";
delete[] buf;
}เลือกใช้ตัวชี้อัจฉริยะ
C++ สมัยใหม่หลีกเลี่ยงการใช้ new/delete โดยตรง std::unique_ptr และ std::make_unique จะคืนหน่วยความจำโดยอัตโนมัติเมื่อตัวชี้ออกจากขอบเขต
#include <iostream>
#include <memory>
int main() {
auto p = std::make_unique<int>(42);
std::cout << *p << "\n";
} // freed automaticallyต้นทุนของฮีป
การจัดสรรบนฮีปช้ากว่าบนสแตก เพราะต้องค้นหาบล็อกว่างและปรับปรุงข้อมูลกำกับการจัดการ การจัดสรรขนาดเล็กบ่อยครั้งอาจทำให้ประสิทธิภาพลดลง
จับคู่การจัดสรรทุกครั้ง
กฎสำคัญคือ การใช้ new ทุกครั้งต้องใช้ delete หนึ่งครั้ง และการใช้ new[] ทุกครั้งต้องใช้ delete[] หนึ่งครั้ง ที่ดียิ่งกว่านั้นคือปล่อยให้ตัวชี้อัจฉริยะจัดการให้
ตรวจสอบความเข้าใจอย่างรวดเร็ว
โปรดทดสอบความเข้าใจเรื่องการจัดสรรหน่วยความจำบนฮีป
สรุปทบทวน
คุณได้เรียนรู้การจัดสรรบน ฮีป ด้วย new/new[] และการคืนหน่วยความจำด้วย delete/delete[] ออบเจ็กต์บนฮีปมีอายุยืนยาวกว่าขอบเขตของตนเอง แต่ต้องล้างหน่วยความจำด้วยตนเอง โปรดจับคู่การจัดสรรทุกครั้ง กำหนดตัวชี้ที่คืนหน่วยความจำแล้วเป็นค่าว่าง และเลือกใช้ std::unique_ptr ในโค้ดสมัยใหม่
คำถามที่พบบ่อย
บทเรียน “การจัดสรรบนฮีพด้วย new/delete” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การจัดสรรบนฮีพด้วย new/delete” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การจัดสรรบนฮีพด้วย new/delete”
จัดการหน่วยความจำแบบไดนามิก คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การจัดสรรบนฮีพด้วย new/delete” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การจัดสรรบนสแตก
- การจัดสรรบนฮีพด้วย new/delete
- อายุการใช้งานของออบเจกต์
- ข้อบกพร่องของหน่วยความจำที่พบบ่อย