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

AddressSanitizer

ตรวจจับข้อผิดพลาดของหน่วยความจำ

AddressSanitizer เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

AddressSanitizer คืออะไร

AddressSanitizer (เอเอสแซน) เป็นเครื่องมือที่ทำงานบนพื้นฐานของคอมไพเลอร์และตรวจจับข้อผิดพลาดด้านหน่วยความจำขณะโปรแกรมทำงาน ได้แก่ การเข้าถึงนอกขอบเขต การใช้หลังคืนหน่วยความจำ การคืนหน่วยความจำซ้ำ และหน่วยความจำรั่ว เครื่องมือนี้เร็วพอสำหรับการทดสอบในชีวิตประจำวัน

การเปิดใช้เอเอสแซน

เพิ่ม -fsanitize=address ทั้งในขั้นตอนคอมไพล์และลิงก์ และเพิ่ม -g เพื่อให้รายงานอ่านได้ง่าย

g++ -fsanitize=address -g -O1 main.cpp -o app
./app

บัฟเฟอร์บนฮีปล้นขอบเขต

เอเอสแซนจะแจ้งเตือนเมื่อมีการอ่านหรือเขียนเลยบัฟเฟอร์ที่จัดสรรไว้ โปรแกรมนี้เขียนข้อมูลเลยไปหนึ่งสมาชิก

#include <cstdlib>

int main() {
    int* a = (int*)malloc(3 * sizeof(int));
    a[3] = 7; // out of bounds
    free(a);
    return 0;
}

การใช้หลังคืนหน่วยความจำ

การเข้าถึงหน่วยความจำหลังจากคืนหน่วยความจำแล้วถือเป็นพฤติกรรมที่ไม่กำหนดไว้ เอเอสแซนจะแจ้ง heap-use-after-free พร้อมสแตกของตำแหน่งที่คืนและจัดสรรหน่วยความจำ

#include <cstdlib>

int main() {
    int* p = (int*)malloc(sizeof(int));
    free(p);
    *p = 5; // use after free
    return 0;
}

บัฟเฟอร์บนสแตกล้นขอบเขต

เอเอสแซนยังแทรกการตรวจสอบให้กับอาร์เรย์บนสแตกด้วย จึงตรวจจับการเขียนเลยขอบเขตของบัฟเฟอร์ภายในได้

#include <iostream>

int main() {
    int buf[3] = {0, 0, 0};
    for (int i = 0; i <= 3; ++i) buf[i] = i; // i==3 overflows
    std::cout << buf[0] << "\n";
    return 0;
}

การอ่านรายงาน

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

การตรวจจับหน่วยความจำรั่ว

เอเอสแซนมี LeakSanitizer รวมอยู่ในหลายแพลตฟอร์ม โดยรายงานหน่วยความจำที่ไม่เคยถูกคืนเมื่อโปรแกรมสิ้นสุด พร้อมสแตกของการจัดสรร

#include <cstdlib>

int main() {
    int* leaked = (int*)malloc(100); // never freed
    return 0;
}

ตัวเลือกขณะทำงาน

ปรับพฤติกรรมด้วยตัวแปรสภาพแวดล้อม ASAN_OPTIONS เช่น ASAN_OPTIONS=detect_leaks=1:halt_on_error=0

ต้นทุนด้านประสิทธิภาพ

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

ใช้ร่วมกับการทดสอบ

เรียกใช้การทดสอบหน่วยภายใต้เอเอสแซนในการผสานรวมอย่างต่อเนื่อง ข้อบกพร่องจริงจำนวนมากจะแสดงออกก็ต่อเมื่อการทดสอบเรียกใช้โค้ดขณะเปิดตัวตรวจสอบไว้ ควรมีการกำหนดค่าโปรแกรมสร้างแยกต่างหากสำหรับตัวตรวจสอบ

ไม่ใช่สิ่งทดแทนความระมัดระวัง

เอเอสแซนค้นหาข้อบกพร่องได้เฉพาะเส้นทางของโค้ดที่คุณเรียกใช้จริงเท่านั้น ควรใช้ร่วมกับความครอบคลุมการทดสอบที่ดี เพราะแขนงที่มีข้อบกพร่องแต่ไม่เคยถูกเรียกใช้จะยังคงซ่อนอยู่

ตรวจสอบอย่างรวดเร็ว

ทบทวนวิธีเปิดใช้เอเอสแซน

สรุปทบทวน

คุณได้เรียนรู้ AddressSanitizer

  • ตรวจจับการเข้าถึงนอกขอบเขต การใช้หลังคืนหน่วยความจำ การคืนหน่วยความจำซ้ำ และหน่วยความจำรั่ว
  • เปิดใช้ด้วย -fsanitize=address -g
  • รายงานจะระบุข้อผิดพลาดและแสดงสแตกของการจัดสรรหรือคืนหน่วยความจำ
  • ช้าลงประมาณ 2 เท่า เหมาะอย่างยิ่งสำหรับการทดสอบและการผสานรวมอย่างต่อเนื่อง แต่ไม่เหมาะกับรุ่นที่จะนำไปใช้งานจริง

คำถามที่พบบ่อย

บทเรียน “AddressSanitizer” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “AddressSanitizer” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “AddressSanitizer”

ตรวจจับข้อผิดพลาดของหน่วยความจำ คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “AddressSanitizer” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม

ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. การใช้ gdb และ lldb
  2. AddressSanitizer
  3. UBSan และ TSan
  4. พื้นฐาน Valgrind
← กลับไปที่ C++ Academy