Segmentation Fault는 프로세스가 허용되지 않은 메모리 영역에 접근하려고 할 때 운영체제가 발생시키는 치명적인 오류다. 일반적으로 "Segfault" 또는 SIGSEGV 라고도 불리며, 대부분의 경우 잘못된 포인터 접근에서 발생한다.
흔히 C나 C++을 사용할 때 발생하는 오류이며, 메모리 안정성을 직접 관리해야 하는 언어 특성상 자주 마주치게 된다.
Segmentation Fault는 다음과 같은 상황에서 발생할 수 있다:
int *ptr = NULL;
*ptr = 10; // Segfault 발생
int *arr;
arr[0] = 1; // malloc 또는 new를 안함
int arr[5];
arr[10] = 20; // 유효 범위를 벗어남
int *ptr = malloc(sizeof(int));
free(ptr);
*ptr = 5; // 이미 해제된 메모리 접근
char *str = "hello";
str[0] = 'H'; // 문자열 상수는 읽기 전용 메모리일 수 있음
운영체제는 각 프로세스에게 고유한 가상 메모리 공간을 할당하며, 이 공간은 크게 다음 영역으로 나뉜다:
이 중 프로세스는 자신에게 허용된 영역만 접근 가능하다. 만약 다른 영역을 침범하면, 운영체제는 하드웨어 예외(interrupt) 를 감지하여 SIGSEGV 시그널을 보내고, 프로세스를 강제 종료시킨다.
즉, Segmentation Fault는 운영체제가 메모리를 보호하기 위한 안전장치다.
gcc -g main.c -o main
gdb ./main
(gdb) run
(gdb) backtrace
valgrind ./main
malloc, free 순서)| 방법 | 설명 |
|---|---|
| 포인터 초기화 | NULL 또는 유효한 주소로 반드시 초기화할 것 |
| 범위 검사 | 배열이나 포인터 연산 시 인덱스 범위 확인 |
| 동적 메모리 관리 주의 | 할당한 메모리는 반드시 필요 시에만 해제 |
| 상수 문자열 수정 금지 | char str[] = "hello"; 형태로 복사하여 사용 |
| 안전한 함수 사용 | strncpy, snprintf 등 버퍼 제한 함수 사용 |
void recurse() {
int arr[10000];
recurse(); // 무한 재귀 → 스택 오버플로우 → 세그폴트
}
무한 재귀는 스택을 초과하게 되어 결국
Segmentation fault (core dumped)를 발생시킨다.
| 항목 | 설명 |
|---|---|
| 정의 | 접근 불가능한 메모리 영역에 접근 시 발생하는 오류 |
| 시그널 이름 | SIGSEGV |
| 흔한 원인 | NULL 포인터, 범위 초과, 해제된 메모리 접근 등 |
| 방지 방법 | 포인터/배열 관리 철저, 디버깅 도구 활용 |
| 관련 도구 | gdb, valgrind, AddressSanitizer 등 |
Segmentation Fault는 단순한 오류가 아닌, 프로세스가 허용되지 않은 메모리 접근을 시도했음을 운영체제가 감지한 결과이다. 이는 메모리 보호 기법의 일환이며, 시스템 안정성을 위해 반드시 필요한 기능이다.
버그를 피하려면 포인터, 배열, 메모리 관리에 특히 주의하며 코딩 습관을 개선해야 한다.