세그먼테이션 오류란 무엇인가?
세그먼테이션 오류(Segmentation Fault, 흔히 '세그폴트'라고 부름)는 프로그램이 운영체제로부터 접근 권한을 받지 못한 메모리 영역에 접근하려고 할 때 발생하는 대표적인 런타임 오류입니다.
가장 핵심적인 원인은 다음과 같습니다.
- 초기화되지 않은 메모리에 접근하는 경우
- 프로그램에 할당된 메모리 범위를 벗어나 접근하는 경우
- 변경이 금지된 문자열 리터럴(string literal)을 수정하려고 시도하는 경우
이러한 동작이 반드시 세그먼테이션 오류를 유발하는 것은 아니며, 경우에 따라 정상적으로 실행되거나 예측하기 어려운 결과를 낳기도 합니다. 하지만 잠재적으로 심각한 버그의 원인이 되므로 반드시 피해야 합니다.
C/C++에서 세그먼테이션 오류가 발생하는 일반적인 원인
- 배열 범위를 벗어난 접근 — 선언된 크기를 초과하는 인덱스로 배열에 읽기 또는 쓰기를 수행할 때 발생합니다.
- NULL 포인터 역참조 — 유효하지 않은 NULL 값을 가진 포인터에 접근하여 값을 읽거나 쓸 때 발생합니다.
- 해제된(freed) 메모리 역참조 — free() 또는 delete로 이미 반환한 메모리를 다시 사용하는 경우(댕글링 포인터) 발생합니다.
- 초기화되지 않은 포인터 역참조 — 아무 값도 대입되지 않은 포인터를 사용하면 예측 불가능한 메모리 주소에 접근하게 됩니다.
- '&'(주소 연산자)와 '*'(역참조 연산자)의 잘못된 사용 — 두 연산자의 의미를 혼동하면 잘못된 주소에 접근할 수 있습니다.
- printf 및 scanf에서 형식 지정자(format specifier)의 부적절한 사용 — 변수 타입과 맞지 않는 %d, %s, %f 등을 사용하면 메모리가 잘못 해석됩니다.
- 스택 오버플로(Stack Overflow) — 과도한 재귀 호출이나 너무 큰 지역 변수 선언으로 스택 메모리가 고갈될 때 발생합니다.
- 읽기 전용 메모리에 대한 쓰기 — 코드 영역이나 문자열 리터럴처럼 수정이 금지된 메모리에 값을 기록하려 할 때 발생합니다.
디버깅 팁
세그먼테이션 오류를 효율적으로 추적하려면 GDB 같은 디버거로 코어 덤프를 분석하거나, Valgrind·AddressSanitizer 같은 도구를 활용해 메모리 접근 오류를 사전에 검출하는 것이 좋습니다. 포인터 사용 전에는 반드시 NULL 여부를 확인하고, 배열 인덱스 경계를 항상 점검하는 습관이 버그를 크게 줄여줍니다.