Thứ Ba, 31 tháng 3, 2026

Lỗi segmentation fault trong C là gì? 7 nguyên nhân phổ biến + cách fix (dễ hiểu cho người mới)

Trong vô số thứ gây...nhức đầu thì Segmentation fault là một trong những lỗi phổ biến nhất trong C/C++, thường xảy ra khi chương trình truy cập sai vùng nhớ (pointer, array, malloc...).
Thảo luận này sẽ giúp bạn hiểu nhanh nguyên nhân và cách fix.

Nếu bạn từng code C, đã viết tới "en nờ" dòng code và thấy chương trình chạy ngon lành. Chắc chắn bạn sẽ rất tự tin.

Một sáng tinh mơ, cái đầu thông thái của bạn chợt "nảy thêm một ý tưởng vĩ đại", bạn vội vàng bật máy lên, tiếp tục thêm vào những dòng code n+1, n+10...Sau đó phấn khởi bấm Run và chạy thử, hân hoan coi thử thành quả...nhưng tự nhiên "đùng" một phát chương trình tắt, không báo lỗi rõ ràng…

Chúc mừng, bạn vừa gặp segmentation fault.
Nghe có vẻ đáng sợ, nhưng thật ra nó không "ma mị" như tên gọi. Hiểu đúng thì sửa lỗi rất nhanh.



Segmentation fault là gì?

Nói đơn giản:
Segmentation fault xảy ra khi chương trình truy cập vào vùng nhớ không hợp lệ

Ví dụ đời thường dễ hiểu:
  • Bạn có chìa khóa phòng A
  • Nhưng lại cố mở phòng B
  • Hệ điều hành: "Không được phép!" --> và thế là...crash



Dấu hiệu nhận biết

Chương trình tự tắt
Terminal báo:
Segmentation fault (core dumped) hoặc thay vì báo Program finished with exit code 0, sẽ báo một code khác 0.

Để có thể "nhìn thấy" dấu hiệu, bạn hãy chạy thử những code sau trên Online C Compiler
Sau khi bấm Run, bạn sẽ thấy Terminal báo:
Program finished with exit code 139
Press ENTER to exit console.

Thông thường trên Linux, segmentation fault sẽ trả về exit code 139.



7 nguyên nhân phổ biến 

(Nếu đã được "em" segmentation fault ghé thăm thì 99% bạn sẽ dính ít nhất 1 cái)

1. Dùng con trỏ NULL
int *p = NULL;
*p = 10; // crash


Bạn đang ghi dữ liệu vào… "hư không"

2. Truy cập vượt mảng
int arr[3] = {1,2,3};
printf("%d", arr[10]); // crash


Mảng có 3 phần tử, bạn đọc phần tử thứ 11 

3. Quên cấp phát bộ nhớ (malloc)
int *p;
*p = 5; // crash


Bạn chưa thuê nhà, nhưng đã xách vali tới ở… và "xui" cho bạn hệ điều hành là chủ nhà 

4. Dùng bộ nhớ sau khi free
int *p = malloc(sizeof(int));
free(p);
*p = 10; // crash


Bạn đã trả phòng nhưng vẫn quay lại ở

5. Stack overflow (đệ quy vô hạn)
void f() {
    f();
}


Gọi chính nó mãi --> tràn stack --> crash

6. Sai kiểu con trỏ
int x = 10;
char *p = (char*)&x;
printf("%s", p); // nguy hiểm


Đọc sai kiểu --> dữ liệu rác --> crash

7. Truy cập bộ nhớ không thuộc quyền
Ví dụ:
  • Ghi vào vùng read-only
  • Truy cập memory của process khác
Hệ điều hành sẽ chặn ngay



Debug theo kiểu dev "xịn sò"

Cách 1: In log (cách "thủ công" nhưng hiệu quả)

printf("Đến bước 1\n");
printf("Đến bước 2\n");


Xem chương trình chết ở đâu

Ví dụ bạn sửa lại dòng code bên trên như sau:
#include <stdio.h>
int main() {
    char *str = "Hello World"; // Pointer to read-only memory
    printf("Đến bước 1\n");
    str[0] = 'h';               // CRASH: Writing to read-only data
    printf("Đến bước 2\n");
    return 0;
}



Chạy thử trên Online C Compiler 

Kết quả bạn sẽ thấy chương trình chỉ in dòng chữ "Đến bước 1". Điều đó cho thấy chương trình bị lỗi ở dòng code tiếp theo "str[0] = 'h';  "

Cách 2: Dùng gdb (chuẩn dev xịn sò)
gdb ./program
run


Sau đó:
backtrace


Nó sẽ chỉ ra dòng gây lỗi

Cách 3: Compile với flag debug
gcc -g main.c -o main




Cách tránh segmentation fault (dành cho lính mới)
  • Luôn kiểm tra NULL
  • Không truy cập vượt mảng
  • malloc → nhớ free
  • Không dùng pointer bừa bãi
  • Debug từng bước



Một sự thật...biết rồi, khổ lắm, nói mãi!

Có khoảng 90% lỗi segmentation fault đến từ:
  • pointer
  • memory
Nếu bạn thấy khó hiểu, đừng lo, bạn không cô đơn đây là vấn đề thật sự rất...khó hiểu!!



Tổng kết

Segmentation fault không phải lỗi "khó"
Nó chỉ là dấu hiệu bạn đang đụng sai vùng nhớ
Hiểu được:
  • pointer
  • memory
Bạn sẽ xử lý được hầu hết các trường hợp



FAQ nhanh

Segmentation fault có phải lúc nào cũng do pointer không?
Không. Nhưng 80–90% liên quan đến pointer hoặc memory.

Có thể tránh hoàn toàn segmentation fault không?
Gần như không, nhưng bạn có thể giảm rất nhiều nếu quản lý memory tốt.

Vì sao code hôm qua chạy được, hôm nay lại segmentation fault?
Thường do thay đổi nhỏ trong memory, pointer hoặc dữ liệu đầu vào.