디버깅과 코드 품질: Sanitizer, 경고, Assert로 메모리 버그 찾기
23강. 디버깅과 코드 품질: Sanitizer, 경고, Assert로 메모리 버그 찾기
이번 강의에서 해결할 문제
크래시 줄만 보고 null 검사를 추가하면 원인이 수명 종료나 범위 초과일 때 문제가 남습니다. 메모리 버그는 재현 입력, 빌드 설정, 첫 잘못된 접근과 할당·해제 위치를 함께 봐야 합니다.
학습 목표
먼저 알아야 할 핵심 개념
컴파일러 경고는 의심스러운 변환·수명·제어 흐름을 빌드 단계에서 찾습니다. Assert는 개발 중 반드시 참이어야 하는 내부 불변식을 확인합니다. AddressSanitizer는 use-after-free와 범위 오류 같은 메모리 문제를, UndefinedBehaviorSanitizer는 지원되는 UB를 찾습니다. ThreadSanitizer는 지원 환경에서 데이터 레이스를 검사합니다.
왜 이 문제가 위험한가
Sanitizer는 모든 버그를 찾는 증명이 아니며 컴파일러·플랫폼별 지원 범위가 다릅니다. 보고서 마지막 크래시 줄만 보면 원인보다 증상을 고칠 수 있습니다. Assert를 사용자 입력 검증에 사용하면 Release에서 제거될 수 있어 오류 처리가 사라질 수 있습니다.
가장 작은 예제로 시작하기
#include <cassert>
#include <iostream>
#include <optional>
#include <vector>
std::optional<int> valueAt(const std::vector<int>& values, std::size_t index) {
if (index >= values.size()) return std::nullopt;
return values[index];
}
int sumKnownNonEmpty(const std::vector<int>& values) {
assert(!values.empty() && "caller must provide at least one value");
int total{};
for (const int value : values) total += value;
return total;
}
int main() {
const std::vector<int> values{3, 5};
if (const auto value = valueAt(values, 3)) std::cout << *value << '\n';
else std::cout << "out of range\n";
std::cout << sumKnownNonEmpty(values) << '\n';
}
코드 한 줄씩 이해하기
- 외부에서 들어올 수 있는 범위 오류는 optional 결과로 처리합니다.
- 내부 호출 계약은 Assert로 개발 빌드에서 확인합니다.
- Assert가 있어도 UB를 일부러 실행하지 않습니다.
- 범위 기반 for가 유효한 원소만 순회합니다.
- 경고와 Sanitizer는 이 안전한 기준선이 통과해야 합니다.
실행 결과와 메모리·동작 흐름
출력은 out of range, 8입니다. 잘못된 인덱스는 vector를 접근하기 전에 거부됩니다. 내부 합계 함수는 비어 있지 않다는 호출자 불변식을 Debug에서 검사합니다.
단계별 실습
흔한 실수와 해결 방법
언제 사용하고 언제 피할까
경고는 항상 기준선으로, Assert는 내부 불변식에, Sanitizer는 Debug·테스트 구성의 메모리·UB·경쟁 조사에 사용합니다. 운영 사용자 오류를 Assert 하나로 처리하거나 성능 측정 결과를 Sanitizer 빌드와 혼동하지 않습니다.
게임 개발 연결
Unreal의 check, ensure, 로그·프로파일 도구는 표준 assert와 목적·빌드 동작이 다릅니다. 엔진 매크로의 배포 구성 동작을 확인하고 사용자 입력·네트워크 오류를 강제 중단으로 처리하지 않습니다. 일반 C++ 모듈에는 지원되는 Sanitizer와 정적 분석을 함께 적용할 수 있습니다.
이해 점검 질문 3개
- Assert와 사용자 입력 오류 반환은 왜 서로 대체할 수 없나요?
- Sanitizer 보고서에서 첫 잘못된 접근과 할당·해제 위치를 함께 봐야 하는 이유는 무엇인가요?
- Sanitizer 통과가 모든 메모리 버그 부재를 증명하지 못하는 이유는 무엇인가요?
핵심 요약
다음 강의 연결
24강. 최종 작업 큐와 리소스 관리 도구에서 소유권·STL·오류와 도구 검증을 하나의 프로젝트로 통합합니다.
디버깅과 코드 품질: Sanitizer, 경고, Assert로 메모리 버그 찾기 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.