0Pricing
C++ Academy · บทเรียน

การจัดสรรบนฮีพด้วย 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การจัดสรรบนสแตก
  2. การจัดสรรบนฮีพด้วย new/delete
  3. อายุการใช้งานของออบเจกต์
  4. ข้อบกพร่องของหน่วยความจำที่พบบ่อย
← กลับไปที่ C++ Academy