Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

สาเหตุการ Crash ของโปรแกรม C++

พฤติกรรมผิดปกติของโปรแกรม C++ มักนำไปสู่การ Crash คุณอาจเคยเจอปัญหาเช่น Segmentation fault, Aborted, Floating point exception เป็นต้น บทความนี้สรุปสาเหตุหลักพร้อมตัวอย่างโค้ด

1. Exception ที่ไม่ได้จัดการ (Unhandled Exceptions)

Exception ใน C++ คือการตอบสนองเมื่อโปรแกรมเจอสภาวะผิดปกติ หากไม่จัดการด้วย try-catch จะทำให้โปรแกรม Crash

ตัวอย่าง: Divide by Zero

#include <iostream>
int main() {
    int num1 = 10;
    int num2 = 0;
    int quotient = num1 / num2;  // Floating point exception (SIGFPE)
    cout << "Quotient: " << quotient;
    return 0;
}

Output: Floating point exception (core dumped)

การหาร int ด้วย 0 ใน C++ เป็น Undefined Behavior บน x86 Linux มักส่งสัญญาณ SIGFPE

2. Buffer Overflow

เมื่อเขียนข้อมูลเกินขนาดบัฟเฟอร์ ข้อมูลล้นจะเขียนทับหน่วยความจำติดกัน

ตัวอย่าง

#include <iostream>
#include <cstring>
int main() {
    int num = 100;
    cout << "Value for num: " << num << endl;
    char c[2];
    strcpy(c, "abcdefghijklmnopqrstuvwxyz");  // เขียนเกิน 2 ไบต์
    cout << "Value for c: " << c << endl;
    return 0;
}

Output: Segmentation fault (core dumped)

เขียนทับตัวแปร num หรือข้อมูลควบคุม stack ทำให้ crash

3. Stack Overflow

เกิดเมื่อ Call stack เกินขนาดจำกัด สาเหตุหลัก: Infinite Recursion

ตัวอย่าง

#include <iostream>
int factorial(int n) {
    if (n == 0) return 1;
    return factorial(n);  // Bug: ควรเป็น factorial(n-1) → Infinite recursion
}
int main() {
    cout << factorial(10);
    return 0;
}

Output: Segmentation fault (core dumped)

4. Segmentation Fault (Segfault)

เกิดเมื่อเข้าถึงหน่วยความจำที่ไม่ได้รับอนุญาต (เข้าถึง NULL pointer, เขียน read-only memory, stack overflow, buffer overflow)

ตัวอย่าง: เขียนทับหน่วยความจำผ่าน pointer

#include <iostream>
int main() {
    char* str;
    char name[] = "iostream";
    str = name;
    while (1) *str++ = 'a';  // เขียนเกินขนาด name[] → segfault
    return 0;
}

5. Memory Leaks

เกิดเมื่อจองหน่วยความจำแบบไดนามิก (new, malloc) แต่ไม่คืน (delete, free) สะสมไปเรื่อยๆ จนหน่วยความจำหมด → Crash

ตัวอย่าง

#include <iostream>
#include <cstdlib>
int main() {
    while (true) {
        int* node = (int*)malloc(9999999);  // จอง ~10MB ต่อรอบ
        // free(node);  // ลืมคืน → Memory leak
    }
    return 0;
}

สาเหตุ Crash อื่นๆ

เครื่องมือช่วย Debug

  • GDB – Debugger มาตรฐาน Linux (gdb ./a.out core)
  • Valgrind – ตรวจ Memory leak, Invalid access (valgrind ./a.out)
  • AddressSanitizer (ASan) – Compiler flag -fsanitize=address ตรวจ buffer overflow, use-after-free
  • UndefinedBehaviorSanitizer (UBSan) – -fsanitize=undefined
  • Core Dump Analysis – ulimit -c unlimited แล้วดู core file

แนวทางป้องกัน

  1. ใช้ Smart Pointers (unique_ptr, shared_ptr) แทน raw pointer
  2. ใช้ Container มาตรฐาน (vector, string) แทน array ดิบ
  3. ตรวจสอบ bounds ก่อนเข้าถึงอาร์เรย์
  4. จัดการ Exception ด้วย try-catch
  5. ใช้ std::optional แทนคืนค่า NULL
  6. Enable compiler warnings: -Wall -Wextra -Wpedantic
  7. ใช้ Static Analysis (Clang-Tidy, Cppcheck)
สาเหตุตัวอย่างสัญญาณ
Dangling Pointerใช้ pointer หลัง delete/freeSIGSEGV
Double Freefree/deleted เดียวกัน 2 ครั้งSIGABRT
Use After Returnคืน reference ของ local variableSIGSEGV
Race ConditionMulti-thread เขียนข้อมูลร่วมกันไม่ syncNon-deterministic
Stack Corruptionเขียนทับ return addressSIGSEGV