สัปดาห์ที่ 3 Pointer และ Dynamic Memory

จุดประสงค์การเรียนรู้

  1. อธิบายหลักการอ้างอิงหน่วยความจำด้วย Pointer ได้
  2. ใช้ Pointer Arithmetic และ Dynamic Memory ได้อย่างระมัดระวัง
  3. วิเคราะห์ Memory Leak, Dangling Pointer และ Buffer Overflow ได้

เนื้อหา

Pointer

Pointer ใช้เก็บตำแหน่งหน่วยความจำของข้อมูล ช่วยให้โปรแกรมส่งค่าขนาดใหญ่ จัดการโครงสร้างข้อมูล และควบคุมทรัพยากรได้ยืดหยุ่นขึ้น แต่ต้องระวังการอ้างอิงตำแหน่งที่ไม่ถูกต้อง

Pointer Arithmetic

Pointer Arithmetic เป็นการเลื่อนตำแหน่งหน่วยความจำตามชนิดข้อมูล เช่น การเดินอ่าน Array ผ่าน Pointer ผู้เรียนต้องเข้าใจขนาดของข้อมูลและขอบเขตหน่วยความจำ

Dynamic Memory

Dynamic Memory คือการจองและคืนหน่วยความจำระหว่างโปรแกรมทำงาน เช่น malloc/free หรือ new/delete เหมาะกับข้อมูลที่ขนาดเปลี่ยนแปลงได้

Memory Error

ข้อผิดพลาดสำคัญได้แก่ Memory Leak จากการไม่คืนหน่วยความจำ Dangling Pointer จากการอ้างอิงพื้นที่ที่ถูกคืนแล้ว และ Buffer Overflow จากการเขียนเกินขอบเขต

Workshop

สร้างโปรแกรมจัดเก็บข้อมูลแบบ Dynamic Array พร้อมตรวจสอบและแก้ปัญหา Memory Leak

รายละเอียดการเรียนรู้

ผู้เรียนฝึกมองหน่วยความจำเป็นตำแหน่งและค่าที่จัดเก็บอยู่ในตำแหน่งนั้น โดยเริ่มจากการประกาศตัวแปร การใช้ address-of operator การ dereference และความสัมพันธ์ระหว่าง Pointer กับ Array จากนั้นจึงเข้าสู่การจองหน่วยความจำแบบ Dynamic เพื่อรองรับข้อมูลที่ไม่ทราบจำนวนล่วงหน้า

ประเด็นสำคัญคือการกำหนดเจ้าของหน่วยความจำให้ชัดเจนว่าใครเป็นผู้จอง ใครเป็นผู้ใช้ และใครเป็นผู้คืนหน่วยความจำ เพื่อป้องกัน Memory Leak และ Dangling Pointer ผู้เรียนควรตรวจสอบค่าที่ return จากการจองหน่วยความจำและกำหนดค่า pointer หลังคืนหน่วยความจำให้ปลอดภัย

แนวปฏิบัติ

  1. ตรวจสอบ pointer ก่อนใช้งาน
  2. ไม่อ่านหรือเขียนเกินขอบเขต array
  3. คืนหน่วยความจำทุกครั้งเมื่อเลิกใช้
  4. หลีกเลี่ยงการมี pointer หลายตัวถือครองทรัพยากรเดียวกันโดยไม่จำเป็น

แบบฝึกหัด

สร้าง Dynamic Array ที่เพิ่มข้อมูลได้ ลบข้อมูลได้ แสดงข้อมูลได้ และมีฟังก์ชัน cleanup สำหรับคืนหน่วยความจำ

รูปแบบการนำเสนอเพิ่มเติมตามแม่แบบ

Pointer คือ ตัวแปรที่เก็บตำแหน่งหน่วยความจำ ส่วน Dynamic Memory คือ หน่วยความจำที่จองระหว่างโปรแกรมทำงาน ผู้เรียนต้องเข้าใจความสัมพันธ์ระหว่าง เจ้าของหน่วยความจำ (Owner), ผู้ใช้ข้อมูล (User) และ ผู้คืนทรัพยากร (Cleanup) ให้ชัดเจน

%%{init: {'theme': 'base', 'themeVariables': {
  'background': '#282828',
  'primaryColor': '#3c3836',
  'primaryTextColor': '#fbf1c7',
  'primaryBorderColor': '#fabd2f',
  'lineColor': '#8ec07c',
  'secondaryColor': '#504945',
  'tertiaryColor': '#665c54',
  'fontFamily': 'Arial'
}}}%%
flowchart LR
  A[Allocate
จองหน่วยความจำ] --> B[Use
ใช้งานข้อมูล] B --> C[Validate
ตรวจขอบเขต] C --> D[Free/Delete
คืนหน่วยความจำ] D --> E[Null Pointer
ตั้งค่าให้ปลอดภัย]

สมการคำนวณพื้นที่หน่วยความจำของ Array

M=n×s

ตัวอย่างโค้ดทดลอง

#include <iostream>
using namespace std;

int main() {
    int size = 3;
    int* numbers = new int[size]; // จองหน่วยความจำแบบ dynamic

    for (int i = 0; i < size; i++) {
        numbers[i] = (i + 1) * 10; // กำหนดค่าตัวอย่าง
    }

    for (int i = 0; i < size; i++) {
        cout << numbers[i] << endl; // expected: 10, 20, 30
    }

    delete[] numbers; // คืนหน่วยความจำ
    numbers = nullptr; // ป้องกัน dangling pointer
    return 0;
}
ความเสี่ยง สาเหตุ วิธีป้องกัน
Memory Leak จองแล้วไม่คืน ใช้ cleanup ทุกครั้ง
Dangling Pointer ใช้ pointer หลัง delete ตั้งค่าเป็น nullptr
Buffer Overflow เขียนเกินขอบเขต ตรวจ index ก่อนใช้งาน

กลับรายวิชา